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获取Linux下文件版本信息、公司名和产品名的方法
Oct 05 Python
python3实现暴力穷举博客园密码
Jun 19 Python
Python 遍历列表里面序号和值的方法(三种)
Feb 17 Python
Tensorflow简单验证码识别应用
May 25 Python
将TensorFlow的模型网络导出为单个文件的方法
Apr 23 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
Feb 08 Python
PyQt5内嵌浏览器注入JavaScript脚本实现自动化操作的代码实例
Feb 13 Python
django 使用全局搜索功能的实例详解
Jul 18 Python
django获取from表单multiple-select的value和id的方法
Jul 19 Python
flask框架url与重定向操作实例详解
Jan 25 Python
Django 5种类型Session使用方法解析
Apr 29 Python
Pytest allure 命令行参数的使用
Apr 18 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实现股票趋势图和柱形图
2015/02/07 PHP
PHP自定义函数实现数组比较功能示例
2017/10/19 PHP
基于jquery的内容循环滚动小模块(仿新浪微博未登录首页滚动微博显示)
2011/03/28 Javascript
IE和Firefox的Javascript兼容性总结[推荐收藏]
2011/10/19 Javascript
ASP.NET中AJAX 调用实例代码
2012/05/03 Javascript
js的alert弹出框出现乱码解决方案
2013/09/02 Javascript
JavaScript加强之自定义event事件
2013/09/21 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
2种jQuery 实现刮刮卡效果
2015/02/01 Javascript
JS实现跟随鼠标闪烁转动色块的方法
2015/02/26 Javascript
JS替换字符串中空格方法
2015/04/17 Javascript
分享纯手写漂亮的表单验证
2015/11/19 Javascript
分享有关jQuery中animate、slide、fade等动画的连续触发、滞后反复执行的bug
2016/01/10 Javascript
第三篇Bootstrap网格基础
2016/06/21 Javascript
AngularJS使用ng-inlude指令加载页面失败的原因与解决方法
2017/01/19 Javascript
Jquery实时监听input value的实例
2017/01/26 Javascript
jQuery中的类名选择器(.class)用法简单示例
2018/05/14 jQuery
jquery.onoff实现简单的开关按钮功能(推荐)
2018/05/24 jQuery
node版本管理工具n包使用教程详解
2018/11/09 Javascript
vue-cli3项目展示本地Markdown文件的方法
2019/06/07 Javascript
你不知道的SpringBoot与Vue部署解决方案
2020/11/09 Javascript
python操作gmail实例
2015/01/14 Python
深入理解python对json的操作总结
2017/01/05 Python
Django数据库类库MySQLdb使用详解
2019/04/28 Python
Django结合ajax进行页面实时更新的例子
2019/08/12 Python
Python Tornado之跨域请求与Options请求方式
2020/03/28 Python
简单介绍一下pyinstaller打包以及安全性的实现
2020/06/02 Python
最新PyCharm 2020.2.3永久激活码(亲测有效)
2020/11/26 Python
预备党员党课思想汇报
2014/01/13 职场文书
交通事故赔偿协议书
2014/04/15 职场文书
组工干部对照检查材料
2014/08/25 职场文书
2015年服务员个人工作总结
2015/05/27 职场文书
原来实习报告是这样写的呀!
2019/07/03 职场文书
创业计划书之青年旅馆
2019/09/23 职场文书
redis实现排行榜功能
2021/05/24 Redis
Java设计模式之代理模式
2022/04/22 Java/Android