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安装与使用redis的方法
Apr 19 Python
利用Python自带PIL库扩展图片大小给图片加文字描述的方法示例
Aug 08 Python
使用paramiko远程执行命令、下发文件的实例
Oct 01 Python
使用实现XlsxWriter创建Excel文件并编辑
May 04 Python
在python 不同时区之间的差值与转换方法
Jan 14 Python
Opencv-Python图像透视变换cv2.warpPerspective的示例
Apr 11 Python
使用Python代码实现Linux中的ls遍历目录命令的实例代码
Sep 07 Python
Series和DataFrame使用简单入门
Nov 13 Python
python matplotlib画盒图、子图解决坐标轴标签重叠的问题
Jan 19 Python
Python 操作 PostgreSQL 数据库示例【连接、增删改查等】
Apr 21 Python
Python如何将装饰器定义为类
Jul 30 Python
matplotlib部件之套索Lasso的使用
Feb 24 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开源建站平台小结
2010/04/22 PHP
Zend Framework缓存Cache用法简单实例
2016/03/19 PHP
PHP实现负载均衡下的session共用功能
2018/04/17 PHP
PHP根据key删除数组中指定的元素
2019/02/28 PHP
Alliance vs Liquid BO3 第三场2.13
2021/03/10 DOTA
javascript之Partial Application学习
2013/01/10 Javascript
jquery实现输入框动态增减的实例代码
2013/07/14 Javascript
window.showModalDialog()返回值的学习心得总结
2014/01/07 Javascript
javascript中Number对象的toString()方法分析
2014/12/20 Javascript
jQuery中change事件用法实例
2014/12/26 Javascript
如何减少浏览器的reflow和repaint
2015/02/26 Javascript
如何利用JSHint减少JavaScript的错误
2016/08/23 Javascript
javascript动画之模拟拖拽效果篇
2016/09/26 Javascript
Javascript中内建函数reduce的应用详解
2016/10/20 Javascript
Radio 单选JS动态添加的选项onchange事件无效的解决方法
2016/12/12 Javascript
JavaScript仿聊天室聊天记录
2016/12/27 Javascript
js 实现复选框只能选择一项的示例代码
2018/01/23 Javascript
微信小程序swiper实现文字纵向轮播提示效果
2020/01/21 Javascript
vue + node如何通过一个Txt文件批量生成MP3并压缩成Zip
2020/06/02 Javascript
[04:46]2018年度玩家喜爱的电竞媒体-完美盛典
2018/12/16 DOTA
python操作excel的包(openpyxl、xlsxwriter)
2018/06/11 Python
python语言元素知识点详解
2019/05/15 Python
python/Matplotlib绘制复变函数图像教程
2019/11/21 Python
python实现udp传输图片功能
2020/03/20 Python
python opencv实现图片缺陷检测(讲解直方图以及相关系数对比法)
2020/04/07 Python
Python任务调度模块APScheduler使用
2020/04/15 Python
TCP/IP的分层模型
2013/10/27 面试题
《童年》教学反思
2014/02/18 职场文书
《大江保卫战》教学反思
2014/04/11 职场文书
汽车维修专业自荐书
2014/05/26 职场文书
档案保密承诺书
2014/06/03 职场文书
雷锋式好少年事迹材料
2014/08/17 职场文书
北京离婚协议书范文2014
2014/09/29 职场文书
2015年领导干部廉洁自律工作总结
2015/05/26 职场文书
标准演讲稿格式结尾应该怎么书写?
2019/07/17 职场文书
Java实现多线程聊天室
2021/06/26 Java/Android