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实现计算两个时间之间相差天数的方法
May 10 Python
浅谈python中的占位符
Nov 09 Python
python登录并爬取淘宝信息代码示例
Dec 09 Python
Flask实现跨域请求的处理方法
Sep 27 Python
详解Python logging调用Logger.info方法的处理过程
Feb 12 Python
从列表或字典创建Pandas的DataFrame对象的方法
Jul 06 Python
Python 3.8正式发布,来尝鲜这些新特性吧
Oct 15 Python
Python脚本操作Excel实现批量替换功能
Nov 20 Python
利用Python的sympy包求解一元三次方程示例
Nov 22 Python
Python数据结构dict常用操作代码实例
Mar 12 Python
Python操作Word批量生成合同的实现示例
Aug 28 Python
Python获取百度热搜的完整代码
Apr 07 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文件上传表单摘自drupal的代码
2011/02/15 PHP
PHP中使用Memache作为进程锁的操作类分享
2015/03/30 PHP
如何在HTML 中嵌入 PHP 代码
2015/05/13 PHP
详解PHP编码转换函数应用技巧
2016/10/22 PHP
Laravel第三方包报class not found的解决方法
2019/10/13 PHP
JS option location 页面跳转实现代码
2008/12/27 Javascript
使用JavaScript动态设置样式实现代码及演示动画
2013/01/25 Javascript
jQuery插件实现表格隔行变色及鼠标滑过高亮显示效果代码
2016/02/25 Javascript
JavaScript编写检测用户所使用的浏览器的代码示例
2016/05/05 Javascript
浅析jQuery 3.0中的Data
2016/06/14 Javascript
jQuery中slidedown与slideup方法用法示例
2016/09/16 Javascript
canvas实现图像放大镜
2017/02/06 Javascript
vue学习笔记之指令v-text && v-html && v-bind详解
2017/05/12 Javascript
vue props 单项数据流实例分享
2020/02/16 Javascript
小程序开发之模态框组件封装
2020/04/23 Javascript
详解Webpack4多页应用打包方案
2020/07/16 Javascript
python 正则式 概述及常用字符
2009/05/07 Python
Python3.6 Schedule模块定时任务(实例讲解)
2017/11/09 Python
Python3中的列表,元组,字典,字符串相关知识小结
2017/11/10 Python
使用TensorFlow实现SVM
2018/09/06 Python
Python设计模式之装饰模式实例详解
2019/01/21 Python
Python学习笔记之视频人脸检测识别实例教程
2019/03/06 Python
pandas dataframe的合并实现(append, merge, concat)
2019/06/24 Python
Python中的 is 和 == 以及字符串驻留机制详解
2019/06/28 Python
Python input函数使用实例解析
2019/11/22 Python
Python lxml模块的基本使用方法分析
2019/12/21 Python
python3下pygame如何实现显示中文
2020/01/11 Python
python cookie反爬处理的实现
2020/11/01 Python
一款纯css3实现的响应式导航
2014/10/31 HTML / CSS
What's the difference between Debug and Trace class? (Debug类与Trace类有什么区别)
2013/09/10 面试题
浪漫婚礼主持词
2014/03/14 职场文书
高三励志标语
2014/06/05 职场文书
Mysql中存储引擎的区别及比较
2021/06/04 MySQL
python常见的占位符总结及用法
2021/07/02 Python
django中websocket的具体使用
2022/01/22 Python
mysql使用instr达到in(字符串)的效果
2022/04/03 MySQL