如何解决Pexpect 连接在密码提示后收到 EOF
我正在尝试使用 SSH 连接到设备。早些时候我正在尝试 PXSSH,但它抛出了 EOF 异常。请参考此处:PXSSH Connection fails sometimes randomly after upgrading to Python3。现在我正在尝试使用 pexpect 连接设备,但我面临同样的问题。我写的代码如下:
class MyPXSSH(spawn):
def __init__(self,*args,**kwargs):
super(MyPXSSH,self).__init__(None,**kwargs)
self.PROMPT = r"\[PEXPECT\][\$\#] "
self.PROMPT_SET_SH = r"PS1='[PEXPECT]\$ '"
self.PROMPT_SET_CSH = r"set prompt='[PEXPECT]\$ '"
def login(self,server,username=None,password='',port=None,cmd='ssh',sync_multiplier=5,check_local_ip=False,auto_prompt_reset=True):
if not check_local_ip:
cmd += " -o'NoHostAuthenticationForLocalhost=yes' -o RSAAuthentication=no" \
" -o UserKnownHostsFile=/dev/null -o PubkeyAuthentication=no -o CheckHostIP=no" \
" -o StrictHostKeyChecking=no -q"
cmd += " -p {} {}@{}".format(port,username,server)
spawn._spawn(self,cmd)
expect_list = [r"(?i)are you sure you want to continue connecting",r"[$#]","password:",pexpect.EOF,pexpect.TIMEOUT]
i = self.expect(expect_list)
if i == 0:
self.sendline('yes')
i = self.expect(expect_list)
if i == 2:
self.sendline(password)
i = self.expect(expect_list)
if i == 2:
self.sendline(password)
i = self.expect(expect_list)
if i == 2:
log.error("PERMISSION DENIED. PLEASE CHECK PASSWORD.")
return False
elif i == 3 or i == 1:
if not self.isalive():
raise Exception("Error connecting...")
log.info("CONNECTED!")
log.info("HERE 1")
pass
elif i == 4:
return False
elif i == 3 or i == 1:
if not self.isalive():
log.info(">>>> STATE: {}".format(i))
raise Exception("Error connecting...")
log.info("CONNECTED!")
log.info("HERE 2")
pass
elif i == 4:
return False
elif i == 3 or i == 4:
raise Exception("Error connecting...")
if not self.isalive():
raise Exception("Error connecting...")
self.sendline()
self.expect([pexpect.TIMEOUT,r'[$#]'],timeout=10)
if auto_prompt_reset and not self.set_unique_prompt():
raise Exception("failed to set prompt!")
log.info("CONNECTED!")
return True
def prompt(self,timeout=-1):
if timeout == -1:
timeout = self.timeout
i = self.expect([self.PROMPT,TIMEOUT],timeout=timeout)
if i==1:
return False
return True
def set_unique_prompt(self):
self.sendline("unset PROMPT_COMMAND")
self.sendline(self.PROMPT_SET_SH) # sh-style
i = self.expect ([TIMEOUT,self.PROMPT],timeout=10)
if i == 0: # csh-style
self.sendline(self.PROMPT_SET_CSH)
i = self.expect([TIMEOUT,timeout=10)
if i == 0:
return False
return True
连接确实收到密码提示,但在发送密码后返回 EOF。
备注:
操作系统:macOS
代码适用于 Python 2.7 和 Pexpect 4.2.0,但在 Python 3.9.4 和 Pexpect 4.8.0 上失败
代码也适用于 Paramiko 等其他 ssh 客户端。 [无法使用Paramiko,因为可以发送的命令类型以及其他一些pexpect 支持但Paramiko 不支持的所需功能存在其他问题]
日志:
2021-07-14 19:01:56 - device.py:124 - INFO - Attemping to connect to device on port 10022.
user@localhost's password: password
2021-07-14 19:01:57 - ssh.py:55 - INFO - >>>> STATE: 3
2021-07-14 19:01:57 - ssh.py:113 - CRITICAL - Error connecting...
user@localhost's password: password
2021-07-14 19:02:27 - ssh.py:55 - INFO - >>>> STATE: 3
2021-07-14 19:02:27 - ssh.py:113 - CRITICAL - Error connecting...
编辑: 使用 -vv
输出 sshdebug1: Next authentication method: password
user@localhost's password: password
debug2: we sent a password packet,wait for reply
debug1: Authentication succeeded (password).
Authenticated to localhost ([::1]:10022).
debug2: fd 6 setting O_NONBLOCK
debug1: channel 0: new [client-session]
debug2: channel 0: send open
debug1: Requesting no-more-sessions@openssh.com
debug1: Entering interactive session.
debug1: pledge: network
debug1: client_input_global_request: rtype hostkeys-00@openssh.com want_reply 0
debug2: callback start
debug2: fd 5 setting TCP_NODELAY
debug2: client_session2_setup: id 0
debug2: channel 0: request shell confirm 1
debug2: callback done
debug2: channel 0: open confirm rwindow 0 rmax 32768
debug2: channel 0: rcvd adjust 2097152
debug2: channel_input_status_confirm: type 99 id 0
debug2: shell request accepted on channel 0
debug2: channel 0: read<=0 rfd 6 len 0
debug2: channel 0: read failed
debug2: channel 0: close_read
debug2: channel 0: input open -> drain
debug2: channel 0: ibuf empty
debug2: channel 0: send eof
debug2: channel 0: input drain -> closed
debug1: client_input_channel_req: channel 0 rtype exit-status reply 0
debug2: channel 0: rcvd eof
debug2: channel 0: output open -> drain
debug2: channel 0: obuf empty
debug2: channel 0: close_write
debug2: channel 0: output drain -> closed
debug2: channel 0: rcvd close
debug2: channel 0: almost dead
debug2: channel 0: gc: notify user
debug2: channel 0: gc: user detached
debug2: channel 0: send close
debug2: channel 0: is dead
debug2: channel 0: garbage collecting
debug1: channel 0: free: client-session,nchannels 1
debug1: fd 0 clearing O_NONBLOCK
Transferred: sent 1896,received 2064 bytes,in 0.0 seconds
Bytes per second: sent 123695.8,received 134656.1
debug1: Exit status 0
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。