我正在尝试在Violent Python的第2章中运行通过Pexpect与SSH交互和使用Pxssh强制SSH密码部分中的代码。同时使用child.expect()
和pxssh
我会得到类似的EOF错误。
从Python控制台运行这些命令:
import pexpect
connStr = "ssh root@127.0.0.1"
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', 'root@127.0.0.1']
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 documentation建议使用expect(pexpect.EOF)
来避免生成EOF例外。的确,当我做以下事情时:
connStr = "ssh root@127.0.0.1"
child = pexpect.spawn(connStr)
print child.expect(pexpect.EOF)
结果为0
。
但仍存在以下问题:
child.expect([pexpect.TIMEOUT, ssh_newkey, "[P|p]assword:"])
。为什么我们将列表传递给expect()
?该列表应该包含什么内容?expect(pexpect.EOF)
?我在Mac OS X 10.8.4上运行Python 2.7和pexpect 2.4。
答案 0 :(得分:5)
关于#2:期待EOF在这里是一个红鲱鱼。你不希望登陆时看到EOF,你希望登录时提示输入密码。 pxssh在从ssh登录时返回EOF而没有得到密码提示时踢出该错误。这可能发生,因为它使用ssh -q来获取警告,并且您从ssh收到警告。使用它正在使用的ssh选项并在没有q:
的情况下自己运行它们/ usr / bin / ssh -l root 127.0.0.1
在我的情况下,当ssh因为我正在连接的机器更改了其身份而导致已知的主机违规时,我可以收到此错误消息。
答案 1 :(得分:1)
尝试在self.expect()
中使用pxssh
时出现同样的错误。通过删除'-q'来更改ssh选项对我来说不起作用。
我按照this网站中的说明添加了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)
有了这个,它运作正常!
答案 2 :(得分:0)
我知道这个问题已经问了很长时间,但是我花了很长时间来弄明白这一点,也许我可以帮助下一个遇到这个问题的人。
我发现,问题是由超时引起的。方法login()
具有默认值login_timeout=10
的参数。如果你将它设置为20而不是10,那么本书中的原始脚本工作正常。结果行是:
s.login(host, user, password, login_timeout=20)
也许接下来我应该尝试找出为什么我的ssh登录很慢......