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获取豆瓣电影简介代码分享
Jan 16 Python
Python实现爬取逐浪小说的方法
Jul 07 Python
详解Django中的ifequal和ifnotequal标签使用
Jul 16 Python
python结合API实现即时天气信息
Jan 19 Python
python机器学习理论与实战(五)支持向量机
Jan 19 Python
python爱心表白 每天都是浪漫七夕!
Aug 18 Python
Python+OpenCV+pyQt5录制双目摄像头视频的实例
Jun 28 Python
python中使用while循环的实例
Aug 05 Python
Python容器使用的5个技巧和2个误区总结
Sep 26 Python
基于python2.7实现图形密码生成器的实例代码
Nov 05 Python
Python变量作用域LEGB用法解析
Feb 04 Python
python输入一个水仙花数(三位数) 输出百位十位个位实例
May 03 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
dede3.1分页文字采集过滤规则详说(图文教程)续二
2007/04/03 PHP
深思 PHP 数组遍历的差异(array_diff 的实现)
2008/03/23 PHP
php学习之 循环结构实现代码
2011/06/09 PHP
php自定文件保存session的方法
2014/12/10 PHP
Zend Framework教程之配置文件application.ini解析
2016/03/10 PHP
PHP递归实现层级树状展开
2016/04/01 PHP
PHP赋值的内部是如何跑的详解
2019/01/13 PHP
教你如何使用node.js制作代理服务器
2014/11/26 Javascript
移动端jQuery修正Web页面滑动时div问题的两则实例
2016/05/30 Javascript
jQuery中Ajax全局事件引用方式及各个事件(全局/局部)执行顺序
2016/06/02 Javascript
js改变style样式和css样式的简单实例
2016/06/28 Javascript
JS原型链 详解及示例代码
2016/09/06 Javascript
Ajax的概述与实现过程
2016/11/18 Javascript
JavaScript使用atan2来绘制箭头和曲线的实例
2017/09/14 Javascript
基于webpack.config.js 参数详解
2018/03/20 Javascript
对于防止按钮重复点击的尝试详解
2019/04/22 Javascript
node.js中path路径模块的使用方法实例分析
2020/02/13 Javascript
基于VUE实现判断设备是PC还是移动端
2020/07/03 Javascript
[01:50:49]DOTA2-DPC中国联赛 正赛 PSG.LGD vs Aster BO3 第三场 1月24日
2021/03/11 DOTA
在Linux上安装Python的Flask框架和创建第一个app实例的教程
2015/03/30 Python
Django Admin实现上传图片校验功能
2016/03/06 Python
Python实现类似比特币的加密货币区块链的创建与交易实例
2018/03/20 Python
python加密解密库cryptography使用openSSL生成的密匙加密解密
2020/02/11 Python
详解python常用命令行选项与环境变量
2020/02/20 Python
python爬虫工具例举说明
2020/11/30 Python
Python基于mediainfo批量重命名图片文件
2020/12/29 Python
德国最大的拼图在线商店:Puzzle.de
2016/12/17 全球购物
爱奇艺VIP会员:大剧抢先看
2018/07/11 全球购物
美国礼品卡交易网站:Cardpool
2018/08/27 全球购物
Turnbull & Asser官网:英国皇室御用的顶级定制衬衫
2019/01/31 全球购物
印度在线购买电子产品网站:Croma
2020/01/02 全球购物
最新奶茶店创业计划书
2014/01/25 职场文书
刑事代理授权委托书
2014/09/17 职场文书
领导参观欢迎词
2015/01/26 职场文书
离婚起诉状范本
2015/05/19 职场文书
一年级下册数学教学反思
2016/02/16 职场文书