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
猜你喜欢
- 我们很多时候,特别是在生成任务的时候,都需要一个唯一标识字符串来标识这个任务,比较常用的有生成uuid或者通过时间来生成。uuid的话可以直
- var date = new Date('2016-11-11 11:11:11');document.write(date
- Python 包含6种数据类型,其中Number(数字)、String(字符串)、Tuple(元组)、List(列表)、Dictionary
- <?php $foo = 'Bob'; // 将 'Bob' 赋给 $foo $bar = &
- 今天看到的这篇文章, 让我对Chrome能够带来的影响,有了点新想法。Update: 发现我在跟别人讨论时,比直接写作文说得清楚一些,对这个
- 方法import pandas as pdimport numpy as npimport seaborn as snsdf = pd.Da
- 对于个人站长来说,如何能使自己的网站与众不同、充满个性,一直是不懈努力的目标。除了尽量提高页面的视觉效
- 本文实例讲述了Python图像处理之颜色的定义与使用。分享给大家供大家参考,具体如下:python中的颜色相关的定义在matplotlib模
- 在对列表的元素进行找寻时,会频繁的说到遍历的理念。对于复杂的遍历要求,如多个列表中查找就显然不适合用for循环。本篇所要带来的是zip()
- 2020.2.20 更新日志:本文的初衷是因为安装anaconda的时候你并不知道会包含哪个版本的python,因此我制作了下表如果你使用的
- this指向当前作用域的对象,如果找不到,往上一层找,直到window。this 关键字很好用,很灵活,正因为很灵活,所以一不小心你就会掉进
- 1. 加载数据集这次我们搭建一个小小的多层线性网络对糖尿病的病例进行分类首先先导入需要的库文件先来看看我们的数据集观察可以发现,前八列是我们
- 翻译自StackOverflow中一个关于Python异常处理的问答。问题:为什么“except:pass”是一个不好的编程习惯?我时常在S
- 背景:读取TXT文件,加载到kafka中,然后通过logstash消费kafka中的数据加载到es中第一步:导入相应的依赖包pip inst
- linux下使用python打开terminal时报错场景一:在jenkins上执行自动化任务,测试任务执行时使用jenkins用户(有su
- Python not equal operator returns True if two variables are of same ty
- # set 不支持索引和切片,是一个无需的不重复得到容器# 类似于字典,但是只有key 没有value# 创建集合dic1={}set1={
- 1. 导入库import numpy as np #矩阵运算import matplotlib.pyplot as plt #可视化impo
- 使用xlrd模块和xlwt模块解题思想:xlwt模块是非追加写.xls的模块,所以要借助for循环和列表,来一次性写入,这样就没有追加与非追
- 正文之前前阵子做了个《人工智能》 的课程作业,然后写了个人工智障。。。大概就是个可以跟你下五子棋的傻儿子。。。下面是代码和效果正文 1、 摘