2017-03-02 50 views
-1

我有以下代码(更新包括Pexpect的):如何获取密码提示

import sys 
import subprocess 
import pexpect 
print "0" 
ssh = subprocess.Popen("ssh -A -t [email protected] ssh -A -X [email protected]", 
     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 

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

+0

我建议改用书面密码ssh_keys。你的生活会更轻松,同时更安全。 – mosh442

回答

0

与约翰内斯·霍姆伯格指导:

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 [email protected] ssh -A -X [email protected]" 
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" 
0

密码提示未写入标准输出。你需要像pexpect这样的东西来捕捉它。针对这个讨论有更多的信息:Sending a password over SSH or SCP with subprocess.Popen

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

+0

我调整了我的代码(上面)以包含您的建议,但我仍然遇到同样的问题。 –

+0

@John_F:我已经更新了我的答案。 –