Python 从subprocess运行的子进程中实时获取输出的例子

作者:tinyid 时间:2023-12-24 18:31:10 

有些时候,我们需要将某些程序放到子进程中去运行,以达到整合系统的目的。在Python中,一个非常好的选择就是使用subprocess模块,本模块为开辟子进程去执行子程序提供了统一的接口,更加便于学习和使用。

同时,对于在子进程里的程序,我们希望能够实时获取其输出,以在主进程中打印相关信息,使我们能够了解当前子程序的执行进度。对此,subprocess模块也提供了相应的参数,能够将子程序的标准输出和标准错误输出返回给主程序。

下面,我们就通过一个例子来说明这个功能。首先,我们需要一个用于模拟标准输出和标准错误输出的“子程序”——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程序,我们会看到,每秒会输出一条信息,达到了我们在主程序中,去追踪子程序执行过程的目的。

PS:测试环境是Python3.6.1 Mac版。

来源:https://blog.csdn.net/cnweike/article/details/73620250

标签:Python,subprocess,子进程,输出
0
投稿

猜你喜欢

  • 超详细注释之OpenCV构建透明的叠加层

    2021-08-18 14:51:01
  • Python设计模式之外观模式实例详解

    2022-01-18 16:39:37
  • python3.3教程之模拟百度登陆代码分享

    2023-08-02 23:08:23
  • 使用Numpy读取CSV文件,并进行行列删除的操作方法

    2023-05-05 03:26:11
  • python读取配置文件方式(ini、yaml、xml)

    2022-10-12 05:07:29
  • 巧用overflow属性解决中间间距问题

    2007-12-08 20:26:00
  • Python实现的石头剪子布代码分享

    2023-04-11 09:14:58
  • pdf论文中python画的图Type 3 fonts字体不兼容的解决方案

    2021-01-21 01:05:15
  • tensorflow使用神经网络实现mnist分类

    2023-07-05 10:19:13
  • Python如何筛选序列中的元素的方法实现

    2021-06-12 03:31:51
  • oracle数据库冷备份的方法

    2023-07-19 09:51:19
  • ACCESS的参数化查询,附VBSCRIPT(ASP)和C#(ASP.NET)函数第1/2页

    2024-01-25 10:05:42
  • Python二维列表的创建、转换以及访问详解

    2022-08-09 16:03:15
  • Python绘制正余弦函数图像的方法

    2022-09-22 19:59:06
  • Python实现模拟登录及表单提交的方法

    2021-05-28 19:23:12
  • 也谈javascript程序优化问题

    2008-10-29 11:30:00
  • 用Python的urllib库提交WEB表单

    2023-06-11 00:14:52
  • php+ajax+h5实现图片上传功能

    2024-05-22 10:05:39
  • MySQL系列之十 MySQL事务隔离实现并发控制

    2024-01-25 20:57:35
  • 优化MySQL数据库中的查询语句详解

    2024-01-21 06:17:06
  • asp之家 网络编程 m.aspxhome.com