EOF при использовании pexpect и pxssh

Я пытаюсь запустить код из разделов Взаимодействие с SSH через Pexpect и Подбор паролей SSH с помощью Pxssh из главы 2 Жестокий питон. Используя как child.expect(), так и pxssh, я получаю похожие ошибки EOF.

Выполнение этих команд из консоли Python:

import pexpect
connStr = "ssh [email protected]"
child = pexpect.spawn(connStr)
ret = child.expect([pexpect.TIMEOUT, ssh_newkey, "[P|p]assword:"])

Я получаю этот вывод:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1316, in expect
    return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1330, in expect_list
    return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1401, in expect_loop
    raise EOF (str(e) + '\n' + str(self))
EOF: End Of File (EOF) in read_nonblocking(). Empty string style platform.
<pexpect.spawn object at 0x10180c550>
version: 2.4 ($Revision: 516 $)
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '[email protected]']
searcher: searcher_re:
    0: TIMEOUT
    1: re.compile("Are you sure you want to continue connecting")
    2: re.compile("[P|p]assword:")
buffer (last 100 chars): 
before (last 100 chars): 
after: <class 'pexpect.EOF'>
match: None
match_index: None
exitstatus: 255 
flag_eof: True
pid: 12122
child_fd: 4
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

И запустив эти команды, используя pxssh:

import pxssh
s = pxssh.pxssh()
s.login("127.0.0.1", "root", "1234")

Я получаю этот вывод:

Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pxssh.py", line
 196, in login
    i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:pas
sword)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", TIMEOUT, "(?i)connectio
n closed by remote host"], timeout=login_timeout)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1316, in expect
    return self.expect_list(compiled_pattern_list, timeout, searchwindowsize)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1330, in expect_list
    return self.expect_loop(searcher_re(pattern_list), timeout, searchwindowsize)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/pexpect.py", li
ne 1401, in expect_loop
    raise EOF (str(e) + '\n' + str(self))
EOF: End Of File (EOF) in read_nonblocking(). Empty string style platform.
<pxssh.pxssh object at 0x1016bff90>
version: 2.4 ($Revision: 516 $)
command: /usr/bin/ssh
args: ['/usr/bin/ssh', '-q', '-l', 'root', '127.0.0.1']
searcher: searcher_re:
    0: re.compile("(?i)are you sure you want to continue connecting")
    1: re.compile("[#$]")
    2: re.compile("(?i)(?:password)|(?:passphrase for key)")
    3: re.compile("(?i)permission denied")
    4: re.compile("(?i)terminal type")
    5: TIMEOUT
    6: re.compile("(?i)connection closed by remote host")
buffer (last 100 chars): 
before (last 100 chars): 
after: <class 'pexpect.EOF'>
match: None
match_index: None
exitstatus: None
flag_eof: True
pid: 12136
child_fd: 3
closed: False
timeout: 30
delimiter: <class 'pexpect.EOF'>
logfile: None
logfile_read: None
logfile_send: None
maxread: 2000
ignorecase: False
searchwindowsize: None
delaybeforesend: 0.05
delayafterclose: 0.1
delayafterterminate: 0.1

Я получаю аналогичные результаты, когда заменяю 127.0.0.1 другими хостами и пробую разные комбинации имени пользователя и пароля.

В документации pexpect предлагается использовать expect(pexpect.EOF), чтобы избежать создания исключения EOF. Действительно, когда я делаю следующее:

connStr = "ssh [email protected]"
child = pexpect.spawn(connStr)
print child.expect(pexpect.EOF)

Результат 0.

Но остаются следующие вопросы:

  1. Меня смущает синтаксис книги: child.expect([pexpect.TIMEOUT, ssh_newkey, "[P|p]assword:"]). Почему мы передаем список expect()? Что должен содержать этот список?
  2. Как мне использовать expect(pexpect.EOF), как указано в документации, при использовании pxssh?
  3. Почему код в книге не работает должным образом? Изменилось ли что-то в библиотеке pexpect после публикации книги? Это потому, что я на OS X?

У меня есть Python 2.7 и pexpect 2.4, работающие на Mac OS X 10.8.4.


person mbaytas    schedule 26.07.2013    source источник
comment
Возможно, вы добавили открытый ключ ssh компьютера, который пытается подключиться к хосту. Вы уверены, что при попытке подключения вы получаете запрос пароля?   -  person orezvani    schedule 03.12.2014
comment
Я также сталкиваюсь с той же проблемой. Есть ли решение для этого?   -  person Nikole    schedule 30.04.2015


Ответы (3)


Относительно № 2: Ожидание EOF — отвлекающий маневр. Вы не ожидаете EOF при входе в систему, вы ожидаете запрос пароля при входе в систему. pxssh сбрасывает эту ошибку, когда возвращает EOF при входе в систему из ssh без запроса пароля. Это может произойти из-за того, что он использует ssh -q, чтобы не получать предупреждений, а вы получаете предупреждение от ssh. Возьмите параметры ssh, которые он использует, и запустите их самостоятельно без q:

/usr/bin/ssh -l корень 127.0.0.1

В моем случае я могу получить это сообщение об ошибке, когда ssh выдает нарушение известных хостов из-за того, что машина, к которой я подключаюсь, изменила свою личность.

person David Eison    schedule 22.08.2013

У меня была такая же ошибка при попытке использовать self.expect() в pxssh. Изменение параметров ssh путем удаления «-q» у меня не сработало.

Я следовал инструкциям на этом сайте, добавив pexpect.EOF в качестве одного из входы в self.expect(). Это заставит скрипт ждать, пока не будет получена вся строка, прежде чем выйти при получении EOF:

i = self.expect(["(?i)are you sure you want to continue connecting", original_prompt, "(?i)(?:password.*)|(?:passphrase for key)", "(?i)permission denied", "(?i)terminal type", pexpect.EOF, TIMEOUT, "(?i)connection closed by remote host"], timeout=login_timeout)

С этим работает нормально!

person ejm    schedule 18.02.2016

Я знаю, что прошло много времени с тех пор, как этот вопрос был задан, но мне потребовалось довольно много времени, чтобы понять это, и, возможно, я смогу помочь следующим людям, столкнувшимся с этой проблемой.

Я узнал, что проблема была вызвана тайм-аутом. Метод login() имеет аргумент со значением по умолчанию login_timeout=10. Если вы установите это выше, например, 20 вместо 10, то оригинальный сценарий из книги работает нормально. Результирующая строка:

s.login(host, user, password, login_timeout=20)

Может быть, в следующий раз я должен попытаться выяснить, почему мой вход в систему по ssh такой медленный...

person yakamoz147    schedule 01.04.2018