【问题标题】:Pexpect ssh wrapper gracious quit and silent commandPexpect ssh wrapper 优雅的退出和静默命令
【发布时间】:2015-05-15 00:54:34
【问题描述】:

我想基本上包装交互式 ssh,自动化登录阶段:

child = pexpect.spawn('ssh ...')
child.expect('Pass prompt: ')
child.sendline(password)
child.expect('shell prompt> ')
child.sendline('cd /some/where')
child.interact()

这行得通。然而,当用户退出 shell(不使用 expect 的控制字符)时,他们会得到一个异常(OSError)。 我的解决方案是:

    try:
        child.interact()
    except OSError as err:
        if err.errno == 5 and not child.isalive():
            # print 'Child exited'
            pass
        else:
            raise

还有其他更清洁的解决方案吗?

另外,我想让“cd /some/where”不回显给用户。我试过了:

child.setecho(False)
child.sendline('cd /some/where')
child.setecho(True)

但是这个命令仍然被回显。有没有更正确的方法,或者这是 setecho 中的一个错误?

【问题讨论】:

  • Pexpect 有 pxssh 专门为您包装 ssh。不过,我不知道它是否能更好地处理这种情况。
  • 您可以通过反转 if 条件使其更简洁,因此您不需要 else。

标签: pexpect


【解决方案1】:

最好的方法是使用pxssh 它可以处理生成 SSH 进程时所需的一切

请看下面的代码:

import pxssh
import getpass

def connect():
        try:
            s = pxssh.pxssh()
            s.logfile = open('/tmp/logfile.txt', "w")
            hostname = raw_input('hostname: ')
            username = raw_input('username: ')
            password = getpass.getpass('password: ')
            s.login(hostname, username, password)
            s.sendline('ls -l')   # run a command
            s.prompt()             # match the prompt
            print(s.before)        # print everything before the prompt.
            s.logout()
        except pxssh.ExceptionPxssh as e:
            print("pxssh failed on login.")
            print(e)    

if __name__ == '__main__':
    connect()

【讨论】: