Python中如何记录并打印subprocess子进程的运行日志?
Python 实时打印 apt 命令运行日志方案
完全可以实现和bash环境一致的实时日志输出效果,核心是避免子进程输出被缓存,让apt的输出流实时透传到当前终端。
最简实现(和终端执行效果完全一致)
不需要额外处理输出内容,直接把apt进程的标准流绑定到Python进程的标准流,所有进度、报错、提示都会和你直接在bash敲命令一样实时打印:
import subprocess import os def apt_install(pkg_list: list[str]): run_cmd = ["apt", "install", "-y", *pkg_list] # 配置非交互环境,避免apt弹确认提示卡住 run_env = os.environ.copy() run_env["DEBIAN_FRONTEND"] = "noninteractive" process = subprocess.Popen( run_cmd, stdout=subprocess.STDOUT, stderr=subprocess.STDOUT, env=run_env, text=True, bufsize=1 # 行级缓冲,保证输出实时刷新 ) exit_code = process.wait() if exit_code == 0: print("\n[通知] 所有软件包安装完成") return True print(f"\n[错误] apt执行失败,退出码:{exit_code}") return False # 调用示例 if __name__ == "__main__": # 注意:脚本需要用sudo执行,否则apt会报权限错误 apt_install(["curl", "wget", "htop"])
带状态追踪的实现(可识别未启动/执行中/报错/完成状态)
如果需要明确标记命令运行的各阶段状态,可以逐行读取apt的输出流,实时打印的同时做状态判断:
import subprocess import os from enum import Enum class RunStatus(Enum): NOT_START = "未启动" RUNNING = "执行中" FAILED = "执行报错" FINISHED = "执行完成" def apt_install_track_status(pkg_list: list[str]): run_cmd = ["apt", "install", "-y", *pkg_list] run_env = os.environ.copy() run_env["DEBIAN_FRONTEND"] = "noninteractive" current_status = RunStatus.NOT_START print(f"[状态] {current_status.value}") process = subprocess.Popen( run_cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, env=run_env, text=True, bufsize=1 ) current_status = RunStatus.RUNNING print(f"[状态] {current_status.value}") # 逐行读取实时输出 for output_line in process.stdout: # 直接打印原始日志,和bash展示效果一致 print(output_line.strip()) # 可根据输出关键字自定义错误判断逻辑 if output_line.startswith("E:") or "dpkg: error" in output_line: current_status = RunStatus.FAILED exit_code = process.wait() if exit_code != 0: current_status = RunStatus.FAILED print(f"[状态] {current_status.value},退出码:{exit_code}") return False, current_status current_status = RunStatus.FINISHED print(f"[状态] {current_status.value}") return True, current_status
注意事项
- 所有apt操作需要root权限,运行Python脚本时必须加
sudo,否则会直接触发权限报错 - 必须给apt命令加
-y参数,同时设置DEBIAN_FRONTEND=noninteractive环境变量,否则遇到交互确认时进程会卡住,无任何输出 - 不要使用
subprocess.run(capture_output=True)或者Popen.communicate()读取输出,这两种方式会等命令完全执行结束后才一次性返回所有内容,无法看到实时进度 - 如果需要留存日志,可以在逐行打印的同时将内容写入本地文件,不影响终端实时展示效果
内容的提问来源于stack exchange,提问作者Marco Frag Delle Monache
相关产品推荐
相关产品推荐

