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标准库之Sys模块使用详解
May 23 Python
全面了解Python的getattr(),setattr(),delattr(),hasattr()
Jun 14 Python
Python 操作MySQL详解及实例
Apr 30 Python
为什么选择python编程语言入门黑客攻防 给你几个理由!
Feb 02 Python
python正则表达式去除两个特殊字符间的内容方法
Dec 24 Python
Python实现计算字符串中出现次数最多的字符示例
Jan 21 Python
PyQt打开保存对话框的方法和使用详解
Feb 27 Python
python中的print()输出
Apr 12 Python
解决python使用list()时总是报错的问题
May 05 Python
python opencv 实现读取、显示、写入图像的方法
Jun 08 Python
python实现移动木板小游戏
Oct 09 Python
Pytorch之扩充tensor的操作
Mar 04 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
PHP添加MySQL数据记录代码
2008/06/07 PHP
php根据年月获取季度的方法
2014/03/31 PHP
通过jquery实现tab标签浏览效果
2007/02/20 Javascript
childNodes.length与children.length的区别
2009/05/14 Javascript
Tips 带三角可关闭的文字提示
2010/10/06 Javascript
IE6下出现JavaScript未结束的字符串常量错误的解决方法
2010/11/21 Javascript
基于jQuery的星级评分插件
2011/08/12 Javascript
在新窗口打开超链接的方法小结
2013/04/14 Javascript
jQuery中nextAll()方法用法实例
2015/01/07 Javascript
把Node.js程序加入服务实现随机启动
2015/06/25 Javascript
基于javascript实现简单的抽奖系统
2020/04/15 Javascript
在 Angular2 中实现自定义校验指令(确认密码)的方法
2017/01/23 Javascript
你真的了解BOM中的history对象吗
2017/02/13 Javascript
利用d3.js力导布局绘制资源拓扑图实例教程
2019/01/08 Javascript
vue实现微信二次分享以及自定义分享的示例
2019/03/20 Javascript
Node.js学习之内置模块fs用法示例
2020/01/22 Javascript
CKEditor扩展插件:自动排版功能autoformat插件实现方法详解
2020/02/06 Javascript
JavaScript实现复选框全选和取消全选
2020/11/20 Javascript
Python探索之Metaclass初步了解
2017/10/28 Python
Java及python正则表达式详解
2017/12/27 Python
python测试mysql写入性能完整实例
2018/01/18 Python
pycharm+django创建一个搜索网页实例代码
2018/01/24 Python
在python中利用最小二乘拟合二次抛物线函数的方法
2018/12/29 Python
Python 实现一个手机号码获取妹子名字的功能
2019/09/25 Python
Python转换itertools.chain对象为数组的方法
2020/02/07 Python
详解Python直接赋值,深拷贝和浅拷贝
2020/07/09 Python
html2 canvas生成清晰的图片实现打印功能
2019/09/23 HTML / CSS
印尼在线旅游门户网站:NusaTrip
2019/11/01 全球购物
山海经纬软件测试笔试题和面试题
2013/04/02 面试题
审核会计岗位职责
2013/11/08 职场文书
大气污染防治方案
2014/05/19 职场文书
青年标兵事迹材料
2014/08/16 职场文书
2014年幼儿园小班工作总结
2014/12/04 职场文书
2016年大学光棍节活动总结
2016/04/05 职场文书
python使用shell脚本创建kafka连接器
2022/04/29 Python
python三子棋游戏
2022/05/04 Python