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多进程分块读取超大文件的方法
Apr 13 Python
利用Anaconda简单安装scrapy框架的方法
Jun 13 Python
python3人脸识别的两种方法
Apr 25 Python
python对文件目录的操作方法实例总结
Jun 24 Python
Python实现自定义读写分离代码实例
Nov 16 Python
opencv-python 提取sift特征并匹配的实例
Dec 09 Python
Python tkinter常用操作代码实例
Jan 03 Python
django日志默认打印request请求信息的方法示例
May 17 Python
Python Django中间件使用原理及流程分析
Jun 13 Python
Python图像读写方法对比
Nov 16 Python
快速创建python 虚拟环境
Nov 28 Python
Python matplotlib安装以及实现简单曲线的绘制
Apr 26 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版
2006/10/09 PHP
php下HTTP Response中的Chunked编码实现方法
2008/11/19 PHP
php写的简易聊天室代码
2011/06/04 PHP
php set_time_limit()函数的使用详解
2013/06/05 PHP
php获取数组元素中头一个数组元素值的实现方法
2014/12/20 PHP
PHP中preg_match函数正则匹配的字符串长度问题
2015/05/27 PHP
WordPress中获取页面链接和标题的相关PHP函数用法解析
2015/12/17 PHP
PHP 500报错的快速解决方法
2016/12/14 PHP
详解php框架Yaf路由重写
2017/06/20 PHP
Javascript客户端将指定区域导出到Word、Excel的代码
2008/10/22 Javascript
javascript EXCEL 操作类代码
2009/07/30 Javascript
ExtJS TabPanel beforeremove beforeclose使用说明
2010/03/31 Javascript
jQuery延迟加载图片插件Lazy Load使用指南
2015/03/25 Javascript
实例解析jQuery插件EasyUI最常用的表单验证规则
2015/11/29 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
原生javascript实现解析XML文档与字符串
2016/03/01 Javascript
JS对HTML表格进行增删改操作
2016/08/22 Javascript
JS中如何实现点击a标签返回页面顶部的问题
2017/01/19 Javascript
使用Node.js实现ORM的一种思路详解(图文)
2017/10/24 Javascript
vue.js绑定事件监听器示例【基于v-on事件绑定】
2018/07/07 Javascript
vue富文本框(插入文本、图片、视频)的使用及问题小结
2018/08/17 Javascript
微信小程序云开发实现数据添加、查询和分页
2019/05/17 Javascript
Python之os操作方法(详解)
2017/06/15 Python
python微信跳一跳系列之自动计算跳一跳距离
2018/02/26 Python
Python3实现爬取简书首页文章标题和文章链接的方法【测试可用】
2018/12/11 Python
python实现五子棋小程序
2019/06/18 Python
django使用admin站点上传图片的实例
2019/07/28 Python
Pytorch在NLP中的简单应用详解
2020/01/08 Python
python同义词替换的实现(jieba分词)
2020/01/21 Python
python读写数据读写csv文件(pandas用法)
2020/12/14 Python
Html5无刷新修改browser Url的方法
2014/01/15 HTML / CSS
世界汽车零件:World Car Parts
2019/09/04 全球购物
亲戚结婚的请假条
2014/02/11 职场文书
地球物理学专业推荐信
2014/09/08 职场文书
新员工试用期工作总结2015
2015/05/28 职场文书
「魔法少女伊莉雅」美游粘土人开订
2022/03/21 日漫