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 25 Python
利用Python的装饰器解决Bottle框架中用户验证问题
Apr 24 Python
Python的Flask站点中集成xhEditor文本编辑器的教程
Jun 13 Python
python实现折半查找和归并排序算法
Apr 14 Python
python线程池(threadpool)模块使用笔记详解
Nov 17 Python
Python使用functools实现注解同步方法
Feb 06 Python
python 中if else 语句的作用及示例代码
Mar 05 Python
Python实现E-Mail收集插件实例教程
Feb 06 Python
python仿抖音表白神器
Apr 08 Python
100行Python代码实现每天不同时间段定时给女友发消息
Sep 27 Python
Python PyInstaller库基本使用方法分析
Dec 12 Python
3分钟看懂Python后端必须知道的Django的信号机制
Jul 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
PL-880隐藏功能
2021/03/01 无线电
一些 PHP 管理系统程序中的后门
2009/08/05 PHP
PHP 一个比较完善的简单文件上传
2010/03/25 PHP
php验证是否是md5编码的简单代码
2014/04/01 PHP
windows服务器中检测PHP SSL是否开启以及开启SSL的方法
2014/04/25 PHP
php恢复数组的key为数字序列的方法
2015/04/28 PHP
浅谈PHP封装CURL
2019/03/06 PHP
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
全系IE支持Bootstrap的解决方法
2015/10/19 Javascript
浏览器兼容的JS写法总结
2016/04/27 Javascript
浅析jQuery事件之on()方法绑定多个选择器,多个事件
2016/04/27 Javascript
前端设计师们最常用的JS代码汇总
2016/09/25 Javascript
JS简单获取当前年月日星期的方法示例
2017/02/07 Javascript
vue.js模仿京东省市区三级联动的选择组件实例代码
2017/11/22 Javascript
Vue使用NPM方式搭建项目
2018/10/25 Javascript
小程序二次贝塞尔曲线实现购物车商品曲线飞入效果
2019/01/07 Javascript
jQuery实现的导航条点击后高亮显示功能示例
2019/03/04 jQuery
vue的keep-alive中使用EventBus的方法
2019/04/23 Javascript
vue模仿网易云音乐的单页面应用
2019/04/24 Javascript
JS中的算法与数据结构之字典(Dictionary)实例详解
2019/08/20 Javascript
[49:35]2018DOTA2亚洲邀请赛3月30日 小组赛A组 KG VS TNC
2018/03/31 DOTA
[35:27]完美世界DOTA2联赛循环赛 GXR vs FTD BO2第二场 10.29
2020/10/29 DOTA
python爬取网站数据保存使用的方法
2013/11/20 Python
Python3实现计算两个数组的交集算法示例
2019/04/03 Python
python制作抖音代码舞
2019/04/07 Python
selenium+PhantomJS爬取豆瓣读书
2019/08/26 Python
python 使用三引号时容易犯的小错误
2020/10/21 Python
html5记忆翻牌游戏实现思路及代码
2013/07/25 HTML / CSS
ZWILLING双立人法国网上商店:德国刀具锅具厨具品牌
2019/08/28 全球购物
电子商务毕业生求职信
2013/11/10 职场文书
党的群众路线教育实践活动宣传标语口号
2014/06/06 职场文书
皇城相府导游词
2015/02/06 职场文书
保护地球的宣传语
2015/07/13 职场文书
原生CSS实现文字无限轮播的通用方法
2021/03/30 HTML / CSS
MySQL数据库索引的最左匹配原则
2021/11/20 MySQL
Python&Matlab实现樱花的绘制
2022/04/07 Python