Python subprocess 子进程实时获取输出详解

慢慢来
慢慢来
发布时间:2026-10-13 | 5人浏览过
原创

本文介绍如何使用Python的subprocess模块在父进程中实时获取子进程的标准输出。通过示例演示了因缓冲区导致输出延迟的问题,并给出通过手动刷新缓冲区(flush)实现逐行实时读取的完整代码方案。

Python subprocess 模块简介

在某些系统整合场景中,我们需要将特定程序放入子进程中运行。Python 提供了 subprocess 模块,该模块为创建子进程并执行子程序提供了统一且便捷的接口。

为了在主进程中实时掌握子程序的执行进度,我们需要实时获取其输出信息。subprocess 模块提供了相关参数,允许将子程序的标准输出(stdout)和标准错误(stderr)重定向回主程序。

实时获取子进程输出的示例

下面通过一个具体示例来演示该功能。首先,我们需要编写一个用于模拟标准输出和标准错误输出的“子程序”——subprogram.py:


import sys
import time
 
 
for i in range(5):
  sys.stdout.write('Processing {}\n'.format(i))
  time.sleep(1)
 
for i in range(5):
  sys.stderr.write('Error {}\n'.format(i))
  time.sleep(1)

该程序逻辑简单,分别向标准输出和标准错误写入5条信息,且每条信息输出间隔1秒。接着是驱动该“子程序”运行的“主程序”——main.py:


import shlex
import subprocess
 
if __name__ == '__main__':
  shell_cmd = 'python3 subprogram.py'
  cmd = shlex.split(shell_cmd)
  p = subprocess.Popen(cmd, shell=False, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
  while p.poll() is None:
    line = p.stdout.readline()
    line = line.strip()
    if line:
      print('Subprogram output: [{}]'.format(line))
  if p.returncode == 0:
    print('Subprogram success')
  else:
    print('Subprogram failed')

输出延迟问题与缓冲区机制

在主程序中,我们通过设置 stderr=subprocess.STDOUT 将子程序的标准错误重定向到标准输出,从而可以直接从标准输出中同时获取这两类信息。运行该程序后,预期结果是 main.py 每秒向控制台输出一条信息,但实际现象是等待10秒后一次性显示所有10条输出。

造成这种现象的原因是标准输出和标准错误存在缓冲区机制。系统不会立即返回程序的标准输出内容,而是进行缓存,直到缓冲区满或程序结束强制清空缓存时才进行输出。明确原因后,解决方法也很直接:在子程序中,每次输出后手动清空缓冲区。以下是修改后的 subprogram.py:


import sys
import time
 
 
for i in range(5):
  sys.stdout.write('Processing {}\n'.format(i))
  sys.stdout.flush()
  time.sleep(1)
 
for i in range(5):
  sys.stderr.write('Error {}\n'.format(i))
  sys.stderr.flush()
  time.sleep(1)

解决方案与测试结果

经过上述修改后,再次运行 main.py 程序,可以看到每秒输出一条信息,成功实现了在主程序中追踪子程序执行过程的目标。

注:测试环境为 Python3.6.1 Mac 版。

以上关于 Python 从 subprocess 运行的子进程中实时获取输出的示例内容到此结束,希望能对大家有所帮助。

相关标签:

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表