如何捕获密码提示

How do I capture Password prompt

我有以下代码(已更新以包含 pexpect):

import sys
import subprocess
import pexpect
print "0"
ssh = subprocess.Popen("ssh -A -t username1@200.1.2.3 ssh -A -X username2@10.1.2.3",
        shell = True,
        stdout = subprocess.PIPE,
        stderr = subprocess.PIPE).communicate()
print "1"
child = pexpect.spawn(ssh)
print "2"
child.expect ('password')
print "3"
child.sendline ('password2')
print "4"
result = ssh.stdout.readlines()
if result == []:
        error = ssh.stderr.readlines()
        print >>sys.stderr, "ERROR: %s" % error
else:
        print result

当我 运行 它时,我看到屏幕上打印了零,然后是密码提示。打印 One 的行永远不会执行,因此以下 pexpect 代码也不会执行。我可以作为用户输入密码,但它会挂起。当我用 Ctrl+C 杀死它时,在返回命令提示符之前会出现带有第二个密码提示的第二个登录横幅。有人可以解释如何捕获第一个密码提示,以便程序可以代替用户发送密码吗?另外,有人可以解释为什么我在终止程序之前没有得到结果变量吗?

密码提示未写入标准输出。您需要 pexpect 之类的东西来捕获它。此线程有更多信息:Sending a password over SSH or SCP with subprocess.Popen

编辑: 关于您更新的 pexpect 代码,首先,如果您阅读子进程的文档,您会看到 communicate() 等待进程终止,这就是为什么您的程序挂起直到您终止 ssh 会话。 您对 pexpect.spawn 的调用看起来不对,它需要一个字符串,而不是 Popen 对象。您在这里根本不需要子流程。

在 Johannes Holmberg 的指导下:

import pexpect

prompt = "cisco_prompt"

def start_log():
        global child
        child.logfile = open("/tmp/mylog", "w")

def stop_log():
        global child
        f = open('/tmp/mylog', 'r')
        for line in f:
                cleanedLine = line.strip()
                if cleanedLine: # is not empty
                        print(cleanedLine)
        f.close()
        child.logfile.close

ssh_cmd = "ssh -A -t username1@200.1.2.3 ssh -A -X username2@10.1.2.3"
child = pexpect.spawn(ssh_cmd, timeout=30)
print "Waiting for 1st password prompt"
child.expect ('password')
child.sendline ('password1')
print "Waiting for 2nd password prompt"
child.expect ('password')
child.sendline ('password2')
start_log()
child.expect (prompt)
child.sendline ('conf t')
stop_log()
start_log()
child.expect ('(config)')
stop_log()
print "Ready for more code"
child.close
print "END"