如何捕获密码提示

时间:2017-03-02 14:10:11

标签: python ssh login pexpect

我有以下代码(更新为包括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终止它时,然后在返回命令提示符之前出现带有第二个密码提示的第二个登录横幅。有人可以解释如何捕获第一密码提示,以便程序可以发送密码而不是用户?另外,有人可以解释为什么在我杀死程序之前我没有得到结果变量吗?

2 个答案:

答案 0 :(得分:0)

密码提示不会写入stdout。你需要像pexpect这样的东西才能抓住它。此主题包含更多信息:Sending a password over SSH or SCP with subprocess.Popen

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

答案 1 :(得分:0)

在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"