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笔记(2)
Oct 24 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
Feb 14 Python
python使用matplotlib绘图时图例显示问题的解决
Apr 27 Python
Python 循环语句之 while,for语句详解
Apr 23 Python
Python针对给定列表中元素进行翻转操作的方法分析
Apr 27 Python
数据清洗--DataFrame中的空值处理方法
Jul 03 Python
Python读取excel指定列生成指定sql脚本的方法
Nov 28 Python
Python关于excel和shp的使用在matplotlib
Jan 03 Python
使用Tensorboard工具查看Loss损失率
Feb 15 Python
python中id函数运行方式
Jul 03 Python
Python中openpyxl实现vlookup函数的实例
Oct 28 Python
PyQt QMainWindow的使用示例
Mar 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你的验证码安全码?
2007/01/02 PHP
微信营销平台系统?刮刮乐的开发
2014/06/10 PHP
PHP生成器简单实例
2015/05/13 PHP
yii2超好用的日期组件和时间组件
2016/05/05 PHP
PHP设计模式之模板方法模式定义与用法详解
2018/04/02 PHP
PHP 7.4中使用预加载的方法详解
2019/07/08 PHP
php抽象类和接口知识点整理总结
2019/08/02 PHP
javascript new fun的执行过程
2010/08/05 Javascript
将list转换为json失败的原因
2013/12/17 Javascript
jquery map方法使用示例
2014/04/23 Javascript
jQuery学习笔记之Ajax用法实例详解
2015/12/01 Javascript
DIV随滚动条滚动而滚动的实现代码【推荐】
2016/04/12 Javascript
微信js-sdk上传与下载图片接口用法示例
2016/10/12 Javascript
NodeJS处理Express中异步错误
2017/03/26 NodeJs
js用类封装pop弹窗组件
2017/10/08 Javascript
微信小程序录音与播放录音功能
2017/12/25 Javascript
微信小程序网络请求封装示例
2018/07/24 Javascript
Vue动态获取width的方法
2018/08/22 Javascript
angular 未登录状态拦截路由跳转的方法
2018/10/09 Javascript
基于layui实现高级搜索(筛选)功能
2019/07/26 Javascript
layui动态加载多表头的实例
2019/09/05 Javascript
微信小程序之滑动页面隐藏和显示组件功能的实现代码
2020/06/19 Javascript
微信小程序实现日历小功能
2020/11/18 Javascript
[02:28]PWL开团时刻DAY3——Ink Ice与DeMonsTer之间的勾心斗角
2020/11/03 DOTA
获取python文件扩展名和文件名方法
2018/02/02 Python
python3.x实现发送邮件功能
2018/05/22 Python
Django Rest framework之权限的实现示例
2018/12/17 Python
python整小时 整天时间戳获取算法示例
2019/02/20 Python
python 梯度法求解函数极值的实例
2019/07/10 Python
python遍历文件目录、批量处理同类文件
2019/08/31 Python
pygame实现贪吃蛇游戏(上)
2019/10/29 Python
Python requests模块session代码实例
2020/04/14 Python
俄罗斯玩具、儿童用品、儿童服装和鞋子网上商店:MyToys.ru
2019/10/14 全球购物
带薪年假请假条
2014/02/04 职场文书
质量保证书范本
2014/04/29 职场文书
运动员获奖感言
2014/08/15 职场文书