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


Posted in Python onAugust 14, 2019

有些时候,我们需要将某些程序放到子进程中去运行,以达到整合系统的目的。在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版。

以上这篇Python 从subprocess运行的子进程中实时获取输出的例子就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python学习笔记之常用函数及说明
May 23 Python
零基础写python爬虫之抓取百度贴吧代码分享
Nov 06 Python
Python自动调用IE打开某个网站的方法
Jun 03 Python
Python2.7 实现引入自己写的类方法
Apr 29 Python
Python 获取主机ip与hostname的方法
Dec 17 Python
Python中字符串String的基本内置函数与过滤字符模块函数的基本用法
May 27 Python
Python爬取豆瓣视频信息代码实例
Nov 16 Python
python中如何使用insert函数
Jan 09 Python
Python vtk读取并显示dicom文件示例
Jan 13 Python
python如何通过twisted搭建socket服务
Feb 03 Python
基于Tensorflow:CPU性能分析
Feb 10 Python
Python进程间的通信之语法学习
Apr 11 Python
python3调用windows dos命令的例子
Aug 14 #Python
python脚本执行CMD命令并返回结果的例子
Aug 14 #Python
用Python调用win命令行提高工作效率的实例
Aug 14 #Python
python基础教程之while循环
Aug 14 #Python
Python 实例方法、类方法、静态方法的区别与作用
Aug 14 #Python
Python学习笔记之Break和Continue用法分析
Aug 14 #Python
Python学习笔记之While循环用法分析
Aug 14 #Python
You might like
$_GET['goods_id']+0 的使用详解
2013/06/06 PHP
PHP有序表查找之插值查找算法示例
2018/02/10 PHP
PHP读取目录树的实现方法分析
2019/03/22 PHP
PHP设计模式入门之迭代器模式原理与实现方法分析
2020/04/26 PHP
javascript入门·对象属性方法大总结
2007/10/01 Javascript
jqgrid 简单学习笔记
2011/05/03 Javascript
js完美解决IE6不支持position:fixed的bug
2015/04/24 Javascript
JS模拟酷狗音乐播放器收缩折叠关闭效果代码
2015/10/29 Javascript
实例代码详解javascript实现窗口抖动及qq窗口抖动
2016/01/04 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
如何在Angular.JS中接收并下载PDF
2016/11/26 Javascript
详解angularjs 学习之 scope作用域
2018/01/15 Javascript
详解如何在vue项目中引入elementUI组件
2018/02/11 Javascript
js代码规范之Eslint安装与配置详解
2018/09/08 Javascript
基于vue的验证码组件的示例代码
2019/01/22 Javascript
详解jQuery设置内容和属性
2019/04/11 jQuery
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
微信小程序 高德地图路线规划实现过程详解
2019/08/05 Javascript
利用JavaScript为句子加标题的3种方法示例
2021/01/05 Javascript
Python使用matplotlib的pie函数绘制饼状图功能示例
2018/01/08 Python
Python3之读取连接过的网络并定位的方法
2018/04/22 Python
python3 kmp 字符串匹配的方法
2018/07/07 Python
python 定时器,轮询定时器的实例
2019/02/20 Python
Django2 连接MySQL及model测试实例分析
2019/12/10 Python
PyTorch使用cpu加载模型运算方式
2020/01/13 Python
python Matplotlib基础--如何添加文本和标注
2021/01/26 Python
使用 css3 transform 属性来变换背景图的方法
2019/05/07 HTML / CSS
使用Canvas操作像素的方法
2018/06/14 HTML / CSS
电子信息专业学生自荐信
2013/11/09 职场文书
租车协议书范本
2014/04/22 职场文书
学校领导四风问题整改措施思想汇报
2014/10/09 职场文书
六年级学生期末评语
2014/12/26 职场文书
公司出纳岗位职责
2015/03/31 职场文书
2015年驾驶员工作总结
2015/04/29 职场文书
MySQL 使用自定义变量进行查询优化
2021/05/14 MySQL
关于JavaScript 中 if包含逗号表达式
2021/11/27 Javascript