Как получить запрос пароля

У меня есть следующий код (обновлен для включения 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

Когда я запускаю его, я вижу напечатанный ноль, за которым следует запрос пароля, отображаемый на экране. Строка, которая печатает One, никогда не выполняется, поэтому следующий код pexpect тоже не выполняется. Я могу ввести пароль как пользователь, но затем он зависает. Когда я убиваю его с помощью Ctrl + C, перед возвратом в командную строку появляется 2-й баннер входа в систему с приглашением 2-го пароля. Может кто-нибудь объяснить, как захватить приглашение 1-го пароля, чтобы программа могла отправлять пароль вместо пользователя? Кроме того, может кто-нибудь объяснить, почему я не получаю результирующую переменную, пока не убью программу?


person John_F    schedule 02.03.2017    source источник
comment
Я предлагаю использовать ssh_keys вместо написанных паролей. Ваша жизнь станет проще и в то же время более безопасной.   -  person mosh442    schedule 02.03.2017
comment
К сожалению, это не всегда вариант. У меня есть приложение, которому необходимо подключиться к удаленной системе, для которой я не могу загрузить ключи.   -  person Edward Falk    schedule 25.06.2018


Ответы (2)


Запрос пароля не записывается в стандартный вывод. Вам понадобится что-то вроде pexpect, чтобы захватить его. В этом потоке есть дополнительная информация: Отправка пароля через SSH или SCP с subprocess.Popen

Изменить: что касается вашего обновленного кода pexpect, во-первых, если вы прочитаете документацию для подпроцесса, вы увидите, что Communicat() ожидает завершения процесса, поэтому ваша программа зависает, пока вы не завершите сеанс ssh. И ваш вызов pexpect.spawn выглядит неправильно, он ожидает строку, а не объект Popen. Здесь вам вообще не нужен подпроцесс.

person Johannes Holmberg    schedule 02.03.2017
comment
Я изменил свой код (выше), чтобы включить ваше предложение, но у меня все еще есть те же проблемы. - person John_F; 02.03.2017

Под руководством Йоханнеса Холмберга:

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"
person John_F    schedule 03.03.2017