Windows下用Python的pexpect通过SSH连接设备的超时问题排查
先抓实际交互输出,确认匹配目标是否正确
在标记超时的expect("Password:")代码前,添加打印缓冲区内容的代码,看看plink实际返回了什么:# 发送login root后立即打印当前输出 print("当前输出内容:", repr(ssh_session.before)) print("缓冲区剩余内容:", repr(ssh_session.read_nonblocking(1024)))这能帮你确认是否真的出现了
Password:,还是有其他提示(比如命令回显、拼写差异、额外空格/换行)导致匹配失败。修正
sendline的冗余换行sendline方法会自动在末尾添加换行符(Windows下为\r\n),你额外加的\r会导致发送两次换行,可能让命令执行异常,输出不符合预期。把代码改成:ssh_session.sendline("login root") # 同理,密码发送也改成sendline(pw1),不需要加\r移除不必要的
time.sleep,改用expect等待可靠标识
固定时长的sleep完全不可靠,pexpect的核心就是通过expect等待匹配标识。比如登录service用户后,先等命令行提示符(比如service@192.168.200.220:~$),再发送login root命令:ssh_session.sendline(pw1) # 先匹配service用户的命令提示符,确认登录完成 ssh_session.expect(r'service@192\.168\.200\.220:~#') # 根据实际提示符调整 ssh_session.sendline("login root")检查plink参数,避免隐性交互阻塞
手动执行时可能已经确认过主机密钥,但脚本运行时plink可能弹出密钥确认提示导致卡住。给plink添加-batch参数跳过交互确认,同时修正路径转义(Windows下路径要用双反斜杠或原始字符串):# 用原始字符串避免转义问题 ssh_command = r'"C:\Program Files\PuTTY\plink.exe" -ssh -batch service@192.168.200.220'改用正则表达式匹配,增强容错性
精确字符串匹配容易被额外空格、换行破坏,换成正则表达式匹配:# 匹配前后可能有空格或换行的Password: ssh_session.expect(r'\s*Password:\s*')手动模拟脚本流程,核对每一步输出
直接在命令行执行plink,严格按照脚本步骤操作:登录service→输入pw1→输入login root,仔细观察此时的提示文本,确认是否和脚本中expect的字符串完全一致(包括大小写、标点、前后空格)。
内容的提问来源于stack exchange,提问作者Alex

