如何在Python 2中实现外部进程日志的实时获取?
实现子进程实时输出的解决方案
你的问题核心在于subprocess.check_output会等待子进程完全结束后才返回所有输出,所以没法看到实时进度。要实现像直接运行worker.py那样的逐行实时更新,我们需要改用subprocess.Popen来启动子进程,并实时读取它的输出流。
修改后的caller.py代码(适配Python 2)
import subprocess cmd = ['python', 'worker.py'] # 启动子进程,将stdout和stderr合并到同一个管道 proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) # 逐行读取子进程输出,直到输出结束 for line in iter(proc.stdout.readline, ''): # 直接打印读取到的内容,保留原格式 print line # 等待子进程执行完成,获取返回状态 proc.wait()
适配Python 3的版本
如果你用的是Python 3,代码需要做小调整(处理字节流和print语法):
import subprocess cmd = ['python', 'worker.py'] # 使用text=True将输出转为字符串,同时合并stderr到stdout proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True) # 逐行读取并实时打印 for line in proc.stdout: print(line, end='') # 避免重复添加换行符 proc.wait()
关键原理说明
subprocess.Popen会立即启动子进程,而非等待它结束,我们通过stdout=subprocess.PIPE拿到子进程的输出管道。iter(proc.stdout.readline, '')会循环读取每一行输出,直到子进程关闭输出流(执行完成)。- 加上
stderr=subprocess.STDOUT是为了把子进程的错误输出也实时打印出来,避免遗漏信息。
额外注意事项
如果你的worker.py里的print语句没有换行符(比如用print('...', end='')),子进程的输出会被缓冲,导致没法实时看到内容。这种情况下需要手动刷新输出缓冲区:
- Python 2:导入
sys,每次print后调用sys.stdout.flush() - Python 3:在print里加上
flush=True,比如print('...', flush=True)
不过你的worker.py已经用了带换行的print,所以不需要额外修改~
内容的提问来源于stack exchange,提问作者alphanumeric
相关产品推荐
相关产品推荐

