使用pexpect捕获多条命令输出结果错位 求正确实现方案
pexpect多命令执行与输出捕获问题解决
问题根因
- 提示符匹配规则过于宽松:仅用
bhreddy1作为匹配条件,而切换用户后的初始提示符、每条命令执行完成返回的提示符中都包含该字符串,会导致expect提前匹配到旧的提示符,还没等当前命令执行输出就结束等待,出现输出串位。 - 执行逻辑顺序错误:执行
ls命令完成expect匹配后,先发送了exit命令再打印输出,导致缓冲区内容被后续操作干扰,输出错位。
修复方案
- 明确完整提示符作为匹配规则,比如示例环境的提示符是
bhreddy1@ubuntu:~$,直接匹配完整提示符后缀避免误判,也可以用正则匹配更通用的提示符格式适配不同环境。 - 调整执行顺序:每次发送命令、匹配到新提示符后,先读取输出存储/打印,再执行下一条命令。
- pexpect完全支持将每条命令的输出存入单独变量,所有命令执行完成后统一打印。
修复后可正常运行的代码如下:
import pexpect def main(): # 定义匹配的提示符,可根据实际环境调整,也可以写正则适配动态提示符 PROMPT = r'bhreddy1@ubuntu:~\$ ' # 用字典存储每条命令对应的输出,也可以用列表存储 cmd_output = {} child = pexpect.spawn('sudo su - bhreddy1') # 等待切换用户完成,匹配提示符 child.expect(PROMPT) # 执行第一条命令 df -h child.sendline('df -h') child.expect(PROMPT) # 去掉输出开头的命令回显和首尾空白,不需要可以直接保留child.before.decode() cmd_output['df -h'] = child.before.decode().strip().removeprefix('df -h').strip() # 执行第二条命令 ls child.sendline('ls') child.expect(PROMPT) cmd_output['ls'] = child.before.decode().strip().removeprefix('ls').strip() # 执行退出 child.sendline('exit') child.expect(pexpect.EOF) # 统一打印所有命令输出 print('\nrunning df -h command') print(cmd_output['df -h']) print('\ncompleted df -h command') print('\nrunning ls command') print(cmd_output['ls']) print('\ncompleted ls command') if __name__ == '__main__': main()
补充说明
- 如果你的环境提示符不固定,可以用正则匹配更通用的规则,比如
r'[a-zA-Z0-9]+@[a-zA-Z0-9]+:.*\$ '可以匹配绝大多数普通用户的bash提示符。 child.before返回的是匹配到规则之前的所有缓冲区内容,默认包含你发送的命令本身的回显,不需要的话可以用字符串处理方法去掉。- 命令输出存储支持任意Python数据结构,列表、字典、单独变量都可以,完全可以等所有命令执行完成后再统一处理、打印。
内容的提问来源于stack exchange,提问作者Bindu G
相关产品推荐
相关产品推荐

