Pexpect,运行ssh

我正在做一个Python脚本,我需要产生几个ssh-copy-id进程,他们需要我输入密码,所以我使用PExpect。

我基本上有这样的:

child = pexpect.spawn('command')
child.expect('password:')
child.sendline('the password')

然后我想产生另一个过程,我不再关心这个过程,不管它是否结束。

child = pexpect.spawn('command2')
child.expect('password:')
child.sendline('the password')

代码挂在第二个“产卵”

但是,如果我将第一个调用注释掉,那么第二个调用会起作用,所以我猜测第一个调用仍然在运行或者不能正常工作。

现在,我无法做的另一件事是等到第一个停下来。 我试过了:
child.close() - 挂起(以True和False作为参数)child.read(-1) - 挂起
child.expect(pexpect.EOF) - 它挂起。
child.terminate() - 挂起(用True和False作为参数)

关于可能发生什么的任何想法?
注意:我不是Python专家,我以前从未使用过pexpect,所以任何想法都是值得欢迎的。

谢谢!


更新:这绝对与ssh-copy-id有关,因为在其他进程中,即使它们不返回,spawn也能正常工作。 此外,显然ssh-copy-id从不返回EOF。


幸运的是,OpenSSH客户端似乎对密码非常挑剔,以及它们来自哪里。

你可以尝试使用Paramiko Python SSH2库。 下面是一个简单的例子,说明如何在密码验证中使用它,然后发出一些shell命令( echo "..." >> $HOME/.ssh/authorized_keys是最简单的)来将您的公钥添加到远程主机上。


我想问题是,SSH试图打开PTY,并且出于安全原因,它不适用于PTY以外的其他任何内容。 这与pexpect不适合。

我有另一个SSH客户端:

http://www.digmia.com/index.php?option=com_content&view=article&id=54:Digmia%20Enterprise%20SSH&Itemid=56

它是开源的,你可以使用它。 你试图做的是更多的命令,但你根本不需要期望。

  • 首先根据手册安装它,然后执行如下操作:

  • 运行dssh-agent,添加你需要的密码,如下所示:

    dssh-add -l < passwordfile
    
  • 或者如果它是一台安全的机器,即没有其他人可以登录,这是非常重要的,否则这将是一个巨大的安全漏洞:

    echo "name-of-server;22;root;password;" | dssh-add -l
    
  • password文件会是这样的:

    name-of-server;22;root;password;
    
  • 并且做一些事情(用文件的实际内容替换CONTENTS OF ... ):

    dssh root@name-of-server -- echo "CONTENTS OF ~/.ssh/identity.pub" > .ssh/authorized_keys ; chmod og-w .ssh .ssh/authorized_keys
    
  • 你可以(可选)做

    dssh-add -f passwords
    
  • (确保没有其他人正在做这些事情,否则你会有竞争条件)。

    另外,pexpect可能应该使用dssh本身(所以你不需要使用dssh-agent)。 但是使用dssh-agent更简单,更安全。

    DSSH的安装手册包含在tarball中。

    我不知道这样做的更简单的方法,OpenSSH ssh-copy-id对密码来自哪里很挑剔...


    为了产卵,阅读pexpect文档,我认为它正在等待命令终止。

    根据您的需求,我会提出几种不同的可能性:

    1)杀死产生的过程。 但是,这可能会导致您的操作受到损坏,所以我不知道它是否是您想要的。

    child = pexpect.spawn('command')
    child.expect('password:')
    child.sendline('the password')
    child.close(True)
    

    2)在转移到下一个之前,等待完成初始任务

    child = pexpect.spawn('command')
    child.expect('password:')
    child.sendline('the password')
    child.wait()
    child = pexpect.spawn('command2')
    ...
    

    3)为所有孩子使用不同的实例,然后等待所有的孩子 - 这可能是最好的解决方案

    def exec_command(cmd):
      child = pexpect.spawn(cmd)
      child.expect('password:')
      child.sendline('the password')
      return child
    
    commands = ['command1', 'command2']
    childrens = [exec_command(cmd) for cmd in commands]
    for child in childrens:
      child.wait()    
    

    注意:这里的所有代码都是未经测试的,并且在假设脚本挂起的情况下编写,因为删除生成对象将挂起,直到命令终止。

    链接地址: http://www.djcxy.com/p/42125.html

    上一篇: Pexpect, running ssh

    下一篇: TDD Test Refactoring to support MultiThreading