Python3 pexpect实现SSH登录:控制台输出存文件及EOF问题求助
解决pexpect SSH脚本全程日志保存问题
我来帮你搞定这个日志记录的问题,核心原因是你没用到pexpect专门的日志功能,反而用了sys.stdout重定向的方式,这种方式根本抓不到pexpect会话的全程输出。下面给你详细分析和修改方案:
问题根源
- pexpect的
spawn对象有自己独立的输入输出缓冲区,它的内容不会自动流入系统的sys.stdout,所以你重定向sys.stdout的操作对它完全不起作用。 - 你原来的代码是在输入密码之后才打开日志文件,这就错过了登录过程中的欢迎提示、SSH连接信息这些内容,自然日志里只有最后命令执行的结果。
修改后的完整脚本
#!/usr/bin/env python import pexpect # SSH登录配置 user = "inteuser" host = "146.11.85.xxx" password = "xxxx" command = "ls -l" # 用with语句自动管理日志文件,避免手动关闭的麻烦 with open('prompt.log', "wb") as childlog: # 创建SSH会话时直接指定logfile,全程记录所有输入输出 child = pexpect.spawn(f'ssh -l {user} {host} {command}', logfile=childlog) # 匹配密码提示符并输入密码 child.expect('password:') child.sendline(password) # 等待会话结束(直到EOF) child.expect(pexpect.EOF) # 可选:在控制台打印全程内容,转成字符串更易读 print(child.before.decode('utf-8'))
关键修改点说明
- 使用pexpect原生的
logfile属性:这是pexpect专门为记录会话日志设计的参数,会自动把SSH连接的所有过程(包括欢迎信息、密码提示符、命令输出)以及你发送的内容(比如密码)都写入日志文件,完美覆盖你要的“全程输出”需求。 - 提前指定日志文件:在创建
spawn对象时就设置logfile,这样从SSH连接建立的那一刻起,所有输出都会被记录,不会遗漏任何内容。 - 安全优化(可选):如果你不想把密码也记录到日志里(毕竟敏感信息),可以把
logfile换成logfile_read,这样只会记录子进程返回的内容,不会记录你发送的密码:
child = pexpect.spawn(f'ssh -l {user} {host} {command}', logfile_read=childlog)
- 编码优化(可选):如果希望日志文件是文本格式而不是二进制,可以在创建
spawn时指定编码,同时把文件打开模式改成"w":
with open('prompt.log', "w", encoding='utf-8') as childlog: child = pexpect.spawn(f'ssh -l {user} {host} {command}', logfile=childlog, encoding='utf-8')
这样修改后,你运行脚本,prompt.log里就会包含从SSH连接开始到命令执行完成的所有输出内容,控制台也会打印全程信息,完全满足你的需求。
内容的提问来源于stack exchange,提问作者huang cheng
相关产品推荐
相关产品推荐

