问题
I have the following code (updated to include 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
When I run it, I see the Zero printed followed by the Password prompt displayed on the screen. The line that prints One never executes and so the following pexpect code doesn't either. I can enter the password as a user but then it hangs. When I kill it with Ctrl+C, the 2nd login banner with 2nd Password prompt then appears before returning to the command prompt. Can someone please explain how to capture the 1st Password prompt so the program can send the password instead of the user? Also, can someone please explain why I don't get the result variable until I kill the program?
回答1:
The password prompt isn't written to stdout. You'll need something like pexpect to capture it. This thread has more info: Sending a password over SSH or SCP with subprocess.Popen
Edit: Regarding your updated pexpect code, first of all, if you read the documentation for subprocess, you'll see that communicate() waits for the process to terminate, that's why your program hangs until you kill the ssh session. And your call to pexpect.spawn looks wrong, it expects a string, not a Popen object. You don't need subprocess at all here.
回答2:
With guidance from 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"
来源:https://stackoverflow.com/questions/42557671/how-do-i-capture-password-prompt