Python Subprocess输出异常:子进程输出未被捕获直接显示
解决subprocess捕获不到子进程输出的问题
我之前也踩过这个坑!你的代码逻辑看起来没问题,但子进程输出直接跑到控制台,大概率是下面两个原因之一:
1. 子进程输出到了stderr而非stdout
很多程序会把日志、错误信息甚至部分正常输出写到标准错误流(stderr),而你只捕获了stdout。试试把stderr也重定向过来:
# 方案1:单独捕获stderr和stdout pprocess = subprocess.Popen('PROGRAM', stdout=subprocess.PIPE, stderr=subprocess.PIPE) while True: stdout_line = pprocess.stdout.readline() stderr_line = pprocess.stderr.readline() if stdout_line: print 'output = ', stdout_line if stderr_line: print 'error = ', stderr_line # 进程结束且无剩余输出时退出循环 if pprocess.poll() is not None and not stdout_line and not stderr_line: break # 方案2:把stderr合并到stdout一起捕获 pprocess = subprocess.Popen('PROGRAM', stdout=subprocess.PIPE, stderr=subprocess.STDOUT) while True: output = pprocess.stdout.readline() print 'output = ', output if pprocess.poll() is not None and not output: break
2. 子进程的stdout被缓冲了
默认情况下,子进程的stdout在管道模式下是全缓冲的——只有当缓冲区满或者进程结束时,内容才会被推送到父进程。解决办法有两种:
方法A:禁用子进程的输出缓冲
如果你的PROGRAM是Python脚本,可以在启动时加-u参数强制无缓冲输出:
pprocess = subprocess.Popen(['python', '-u', 'your_script.py'], stdout=subprocess.PIPE)
如果是其他程序,可查看是否有禁用缓冲的命令行参数,或者设置对应环境变量(比如PYTHONUNBUFFERED=1对Python程序有效)。
方法B:在Popen中设置缓冲模式
在Python 2里,你可以用bufsize=0(无缓冲)或者universal_newlines=True(将输出视为文本流,启用行缓冲):
# 无缓冲模式 pprocess = subprocess.Popen('PROGRAM', stdout=subprocess.PIPE, bufsize=0) # 文本模式行缓冲 pprocess = subprocess.Popen('PROGRAM', stdout=subprocess.PIPE, universal_newlines=True)
另外提个小细节:你的while循环没处理进程结束的情况,当子进程跑完后,readline()会一直返回空字符串,导致循环无限运行,记得加上pprocess.poll()的判断来退出循环哦。
内容的提问来源于stack exchange,提问作者Jay R. W
相关产品推荐
相关产品推荐

