应使用subprocess.popen配合stdout=pipe和循环读取实现实时处理;关键点包括避免communicate()、用readline()逐行读、设置text=true、检查poll()、指定encoding;stdin写入需设stdin=pipe并flush();用terminate()/kill()/send_signal()控制生命周期;安全执行优先用列表参数,shell=true时须shlex.quote()。

捕获子进程的输出并实时处理
默认情况下,subprocess.run() 会等待命令执行完毕才返回结果,适合简单场景;但若需边执行边读取输出(比如日志流、进度条、交互式程序),应使用 subprocess.Popen 配合 stdout=PIPE 和循环读取。
关键点:避免直接调用 .communicate() —— 它会阻塞直到子进程结束;改用 .stdout.readline() 或 .stdout.read(1) 实现逐行/逐字节读取。
- 设置
bufsize=1或universal_newlines=True(Python 3.7+ 推荐用text=True)确保按行解码 - 对长时间运行的命令(如
ping -t、tail -f),记得检查proc.poll() is not None判断是否已退出 - 注意编码问题:Windows 下 cmd 默认 GBK,Linux/macOS 一般 UTF-8;显式指定
encoding='utf-8'更稳妥
向子进程输入数据(stdin 写入)
当子进程需要交互式输入(例如 python -c "input()" 或 bc 计算器),可通过 stdin=PIPE 启动进程,再用 proc.stdin.write() + proc.stdin.flush() 发送内容。
BJXSHOP购物管理系统是一个功能完善、展示信息丰富的电子商店销售平台;针对企业与个人的网上销售系统;开放式远程商店管理;完善的订单管理、销售统计、结算系统;强力搜索引擎支持;提供网上多种在线支付方式解决方案;强大的技术应用能力和网络安全系统 BJXSHOP网上购物系统 - 书店版,它具备其他通用购物系统不同的功能,有针对图书销售而进行开发的一个电子商店销售平台,如图书ISBN,图书目录
- 必须在创建 Popen 时设置
stdin=PIPE,否则proc.stdin为None - 写入后务必调用
flush(),否则内容可能滞留在缓冲区不被子进程读到 - 若子进程读完就退出,可配合
proc.wait()等待结束;若需双向通信(即又读又写),建议用subprocess.communicate(input=...)避免死锁
控制子进程生命周期与信号交互
除了启动和等待,常需中断、暂停或强制终止子进程。Python 的 subprocess 提供了跨平台的接口,但行为略有差异。
立即学习“Python免费学习笔记(深入)”;
-
proc.terminate()发送SIGTERM(Unix)或CTRL_BREAK_EVENT(Windows),允许子进程清理后退出 -
proc.kill()发送SIGKILL(Unix)或TerminateProcess(Windows),立即结束,无清理机会 -
proc.send_signal(signal.SIGINT)可模拟 Ctrl+C,适用于希望触发子进程中断逻辑的场景(如 Python 脚本中捕获KeyboardInterrupt) - 注意:子进程的子进程(孙子进程)默认不会被一并终止,如需级联结束,Windows 上可用
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP,Linux/macOS 上建议用preexec_fn=os.setsid+ 杀整个进程组
安全执行外部命令:避免 shell 注入
直接拼接字符串传给 shell=True 极易引发安全问题(如用户输入 ; rm -rf /)。
- 优先使用列表形式调用:
subprocess.run(['ls', '-l', dirname])—— 参数自动转义,无需担心空格或特殊字符 - 仅当必须用 shell 功能(管道
|、重定向>、通配符*)时启用shell=True,且确保所有变量经shlex.quote()处理 - 禁用 shell 的情况下,无法直接使用
&&、||等逻辑操作符;如需条件执行,应在 Python 层判断proc.returncode后决定下一步









