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文件及目录操作实例详解
Jun 04 Python
Python中函数的参数定义和可变参数用法实例分析
Jun 04 Python
pip安装Python库时遇到的问题及解决方法
Nov 23 Python
python3读取excel文件只提取某些行某些列的值方法
Jul 10 Python
python实现五子棋小程序
Jun 18 Python
python字典改变value值方法总结
Jun 21 Python
使用Python计算玩彩票赢钱概率
Jun 26 Python
python选取特定列 pandas iloc,loc,icol的使用详解(列切片及行切片)
Aug 06 Python
Python从文件中读取指定的行以及在文件指定位置写入
Sep 06 Python
浅析Python 简单工厂模式和工厂方法模式的优缺点
Jul 13 Python
如何使用 Flask 做一个评论系统
Nov 27 Python
OpenCV 图像梯度的实现方法
Jul 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
新安装的MySQL数据库需要注意的安全知识
2008/07/30 PHP
PHP学习笔记之数组篇
2011/06/28 PHP
完美解决令人抓狂的zend studio 7代码提示(content Assist)速度慢的问题
2013/06/20 PHP
php利用腾讯ip分享计划获取地理位置示例分享
2014/01/20 PHP
ThinkPHP使用PHPExcel实现Excel数据导入导出完整实例
2014/07/22 PHP
ThinkPHP验证码和分页实例教程
2014/08/22 PHP
PHP获取QQ达人QQ信息的方法
2015/03/05 PHP
php array_key_exists() 与 isset() 的区别
2016/10/24 PHP
DOM精简教程
2006/10/03 Javascript
javascript编程起步(第四课)
2007/01/10 Javascript
找出字符串中出现次数最多的字母和出现次数精简版
2012/11/07 Javascript
javascript不可用的问题探究
2013/10/01 Javascript
JS中用三种方式实现导航菜单中的二级下拉菜单
2016/10/31 Javascript
JS数组排序方法实例分析
2016/12/16 Javascript
详解基于node的前端项目编译时内存溢出问题
2017/08/01 Javascript
让Vue也可以使用Redux的方法
2018/05/23 Javascript
解决Vue axios post请求,后台获取不到数据的问题方法
2018/08/11 Javascript
JavaScript多种图形实现代码实例
2020/06/28 Javascript
python解析xml文件操作实例
2014/10/05 Python
举例详解Python中的split()函数的使用方法
2015/04/07 Python
Python利用operator模块实现对象的多级排序详解
2017/05/09 Python
基于Python列表解析(列表推导式)
2018/06/23 Python
Python中查看变量的类型内存地址所占字节的大小
2019/06/26 Python
Tensorflow 实现分批量读取数据
2020/01/04 Python
Python有参函数使用代码实例
2020/01/06 Python
Keras loss函数剖析
2020/07/06 Python
美国药妆网站:EDCskincare.com(防晒、痤疮、抗衰老等)
2017/04/28 全球购物
美国演唱会订票网站:Ticketmaster美国
2017/10/05 全球购物
校园餐饮创业计划书
2014/01/10 职场文书
石油工程专业毕业生求职信
2014/04/13 职场文书
应届毕业生自荐信
2014/05/28 职场文书
中职生自荐信范文
2014/06/15 职场文书
2014个人年度工作总结
2014/12/15 职场文书
2015年副班长工作总结
2015/05/15 职场文书
【海涛教你打DOTA】剑圣第一人称视角解说
2022/04/01 DOTA
Win11运行育碧游戏总是崩溃怎么办 win11玩育碧游戏出现性能崩溃的解决办法
2022/04/06 数码科技