2017-03-02 55 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:我已經更新了我的答案。 –