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实现的百度站长自动URL提交小工具
Jun 27 Python
在Python中处理日期和时间的基本知识点整理汇总
May 22 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
May 22 Python
Python使用Scrapy爬取妹子图
May 28 Python
python使用win32com库播放mp3文件的方法
May 30 Python
python实现批量修改文件名代码
Sep 10 Python
python实现百度语音识别api
Apr 10 Python
caffe binaryproto 与 npy相互转换的实例讲解
Jul 09 Python
Pycharm无法显示动态图片的解决方法
Oct 28 Python
Python面向对象程序设计OOP入门教程【类,实例,继承,重载等】
Jan 05 Python
如何使用python操作vmware
Jul 27 Python
python retrying模块的使用方法详解
Sep 25 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函数重载的替代方法--伪重载详解
2015/05/08 PHP
php 多文件上传的实现实例
2016/10/23 PHP
win7 wamp 64位 php环境开启curl服务遇到的问题及解决方法
2018/09/16 PHP
php实现的PDO异常处理操作分析
2018/12/27 PHP
JavaScript 语法集锦 脚本之家基础推荐
2009/11/15 Javascript
jQuery 源码分析笔记(4) Ready函数
2011/06/02 Javascript
利用jquery的获取JS文件中的字符串内容
2012/02/14 Javascript
Javascript中数组sort和reverse用法分析
2014/12/30 Javascript
js实现用户离开页面前提示是否离开此页面的方法(包括浏览器按钮事件)
2015/07/18 Javascript
JavaScript学习笔记之数组去重
2016/03/23 Javascript
微信小程序block的使用教程
2018/04/01 Javascript
vue中post请求以a=a&b=b 的格式写遇到的问题
2018/04/27 Javascript
详解React 的几种条件渲染以及选择
2018/10/23 Javascript
node.js监听文件变化的实现方法
2019/04/17 Javascript
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
Vue项目中如何使用Axios封装http请求详解
2019/10/23 Javascript
微信浏览器左上角返回按钮监听的实现
2020/03/04 Javascript
JavaScript布尔运算符原理使用解析
2020/05/06 Javascript
[46:20]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS BO3 第二场 1月22日
2021/03/11 DOTA
Django日志模块logging的配置详解
2017/02/14 Python
Python装饰器用法实例总结
2018/05/26 Python
用Python解数独的方法示例
2019/10/24 Python
Python常见反爬虫机制解决方案
2020/06/01 Python
python3.6.5基于kerberos认证的hive和hdfs连接调用方式
2020/06/06 Python
CSS3 3D位移translate效果实例介绍
2016/05/03 HTML / CSS
JSF面试题:Jsf中导航的标签是什么
2013/04/20 面试题
static函数与普通函数有什么区别
2015/12/25 面试题
英语自荐信范文
2013/12/11 职场文书
校园摄影活动策划方案
2014/02/05 职场文书
手机被没收检讨书
2014/02/22 职场文书
宝宝满月酒主持词和仪式流程
2014/03/27 职场文书
六年级学生期末评语
2014/12/26 职场文书
投资公司董事长岗位职责
2015/04/16 职场文书
公司开业的祝贺语大全(60条)
2019/07/05 职场文书
pytorch中的model.eval()和BN层的使用
2021/05/22 Python