如何在Python的subprocess.Popen中传入Ctrl-C并捕获标准输出?
解决方案
要同时实现捕获stdout解析关键词和向模拟器调试界面发送输入,可以通过调整subprocess.Popen参数并配合线程处理实时输出的方式解决:
核心实现思路
- 用
stdin=subprocess.PIPE接管子进程输入,stdout=subprocess.PIPE捕获输出,stderr=subprocess.STDOUT合并标准错误到标准输出 - 启动独立线程持续读取子进程的stdout,避免主进程被阻塞
- 捕获
KeyboardInterrupt时,先发送SIGINT信号触发调试模式,再通过stdin写入调试界面的退出指令,最后继续监控进程状态
代码示例
import subprocess import sys import signal import threading def parse_output(line): # 替换为你的关键词解析逻辑 if "调试模式已激活" in line: print(f"匹配到目标关键词: {line.strip()}") def read_stdout(proc): while True: line = proc.stdout.readline() if not line: break line_str = line.decode("utf-8") # 根据模拟器实际输出编码调整 parse_output(line_str) # 可选:同步输出到终端,方便调试 sys.stdout.write(line_str) sys.stdout.flush() # 替换为你的模拟器启动命令 cmd = "your_emulator_command" proc = subprocess.Popen( cmd.split(), stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=False # 字节流处理更灵活,避免编码冲突 ) # 启动线程实时读取并解析输出 output_thread = threading.Thread(target=read_stdout, args=(proc,)) output_thread.daemon = True output_thread.start() try: proc.wait() except KeyboardInterrupt: # 发送SIGINT触发调试模式 proc.send_signal(signal.SIGINT) # 向调试界面发送退出指令(替换为模拟器实际退出命令,比如"exit\n") proc.stdin.write(b"quit\n") proc.stdin.flush() # 等待模拟器处理指令并恢复运行 proc.wait() finally: # 释放资源 proc.stdin.close() proc.stdout.close()
关键说明
- 线程读取输出:直接在主进程调用
readline()会阻塞信号处理,线程方式可实现实时解析与主流程不阻塞的平衡 - 编码适配:如果模拟器输出为GBK等非UTF-8编码,需修改
decode的参数;也可设置text=True让subprocess自动处理字符串,但字节流方式兼容性更强 - 输入发送:写入stdin时必须添加换行符
\n,并调用flush()确保数据立即传递给子进程 - 资源清理:finally块中关闭管道,避免子进程资源泄漏
内容的提问来源于stack exchange,提问作者hyperion007
相关产品推荐
相关产品推荐

