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实现的各种排序算法代码
Mar 04 Python
在ironpython中利用装饰器执行SQL操作的例子
May 02 Python
收藏整理的一些Python常用方法和技巧
May 18 Python
Python中threading模块join函数用法实例分析
Jun 04 Python
python实现按任意键继续执行程序
Dec 30 Python
解决pycharm界面不能显示中文的问题
May 23 Python
python语言线程标准库threading.local解读总结
Nov 10 Python
Python 面向对象之封装、继承、多态操作实例分析
Nov 21 Python
PyQt5中向单元格添加控件的方法示例
Mar 24 Python
Python3爬虫中识别图形验证码的实例讲解
Jul 30 Python
Python爬虫代理池搭建的方法步骤
Sep 28 Python
在python中读取和写入CSV文件详情
Jun 28 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
js限制checkbox勾选的个数以及php获取多个checkbbox的方法深入解析
2013/07/18 PHP
php模拟服务器实现autoindex效果的方法
2015/03/10 PHP
PHP连接MYSQL数据库的3种常用方法
2017/02/27 PHP
JQERY limittext 插件0.2版(长内容限制显示)
2010/08/27 Javascript
JavaScript学习笔记记录我的旅程
2012/05/23 Javascript
js实现鼠标拖动图片并兼容IE/FF火狐/谷歌等主流浏览器
2013/06/06 Javascript
js实现的复制兼容chrome和IE
2014/04/03 Javascript
Javascript实现Web颜色值转换
2015/02/05 Javascript
bootstrap fileinput 插件使用项目总结(经验)
2017/02/22 Javascript
微信小程序 共用变量值的实现
2017/07/12 Javascript
使用jQuery实现购物车结算功能
2017/08/15 jQuery
利用纯js + transition动画实现移动端web轮播图详解
2017/09/10 Javascript
vue axios请求超时的正确处理方法
2018/04/02 Javascript
vue-cli 引入jQuery,Bootstrap,popper的方法
2018/09/03 jQuery
react 兄弟组件如何调用对方的方法示例
2018/10/23 Javascript
如何提升vue.js中大型数据的性能
2019/06/21 Javascript
微信小程序在线客服自动回复功能(基于node)
2019/07/03 Javascript
[02:32]DOTA2英雄基础教程 祸乱之源
2013/12/23 DOTA
Python 返回汉字的汉语拼音
2009/02/27 Python
深入理解python多进程编程
2016/06/12 Python
对python多线程与global变量详解
2018/11/09 Python
简单了解django缓存方式及配置
2019/07/19 Python
Python3实现配置文件差异对比脚本
2019/11/18 Python
在Django下创建项目以及设置settings.py教程
2019/12/03 Python
使用pyshp包进行shapefile文件修改的例子
2019/12/06 Python
使用Matplotlib 绘制精美的数学图形例子
2019/12/13 Python
基于TensorFlow的CNN实现Mnist手写数字识别
2020/06/17 Python
HTML5 window/iframe跨域传递消息 API介绍
2013/08/26 HTML / CSS
Sofmap官网:日本著名的数码电器专卖店
2017/05/19 全球购物
五一劳动节演讲稿
2014/09/12 职场文书
领导班子整改措施
2014/10/24 职场文书
小学教师求职信范文
2015/03/20 职场文书
聋哑人盗窃罪辩护词
2015/05/21 职场文书
如何用Python搭建gRPC服务
2021/06/30 Python
Redis官方可视化工具RedisInsight安装使用教程
2022/04/19 Redis
win sever 2022如何占用操作主机角色
2022/06/25 Servers