Python subprocess如何实时输出并将输出与错误保存至文件?
解决Python子进程输出缓冲问题
方法1:给被调用的Python程序添加无缓冲参数
Python在非交互式环境(比如通过管道输出时)默认会启用块缓冲,导致输出无法实时刷新。给python命令加上-u参数可强制开启无缓冲模式,让输出实时打印并写入日志。
修改后的代码:
subprocess.run(f"python -u {args.launch} 2>&1 | tee -a {file_path}", shell=True)
-u参数会让Python的stdout和stderr采用无缓冲的二进制模式,输出会立即推送到管道,tee就能实时捕获并同步输出到屏幕和文件。
方法2:手动处理子进程输出(更安全,规避shell注入风险)
若不想依赖shell=True(避免命令注入隐患),可直接用subprocess.Popen捕获输出,逐行读取后同时打印到屏幕并写入日志文件。
示例代码:
import subprocess with open(file_path, 'a') as log_file: # 启动子进程,合并stdout和stderr proc = subprocess.Popen( ["python", args.launch], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1 # 启用行缓冲 ) # 逐行读取并处理输出 for line in proc.stdout: print(line, end='') # 打印到屏幕,避免重复换行 log_file.write(line) # 写入日志文件 proc.wait() # 等待子进程执行完毕
这种方式不依赖shell的tee命令,完全由Python控制输出流程,既保证实时性,又避免了shell命令拼接带来的安全问题。
补充说明
如果被调用的Python程序本身在打印时添加了flush=True参数(比如print(..., flush=True)),也能缓解缓冲问题,但全局设置-u或手动处理输出的方式更彻底,无需修改被调用程序的代码。
内容的提问来源于stack exchange,提问作者Jojo Zhai
相关产品推荐
相关产品推荐

