实时获取subprocess子进程的输出

2020年1月28日 / 116次阅读 / Last Modified 2020年2月1日
subprocess模块

使用python的subprocess模块创建子进程,本文介绍如何实时获取这种子进程的输出,stdout和stderr。

既然是实时获取subprocess创建的子进程的输出,我们就不能使用run,而要使用Popen创建异步子进程,然后通过poll函数来查看异步子进程的执行状态,如果执行没有结束,我们就直接去读取子进程的stdout,然后在主进程中处理。

下面是子进程的代码,在subproc.py文件中:

import time

while True:
    print('subprocess print...', flush=True)
    time.sleep(1)

注意:print函数一定要使用flush=True,否则子进程的输出都在缓存中,主进程也无法读取出来!

下面是主进程的代码,在proc.py文件中:

from subprocess import *

proc = Popen('python subproc.py', shell=True, stdout=PIPE, stderr=PIPE)
while True:
    rcode = proc.poll()
    if rcode is None:
        print('from subprocess: ', end='')
        line = proc.stdout.readline().strip()
        print(line.decode())

两个.py文件放在同一目录下,下面是执行效果:

E:\py>python proc.py
from subprocess: subprocess print...
from subprocess: subprocess print...
from subprocess: subprocess print...
from subprocess: subprocess print...
from subprocess: subprocess print...
from subprocess: Traceback (most recent call last):
  File "proc.py", line 10, in 
    line = proc.stdout.readline().strip()
KeyboardInterrupt

用这个技术,可以在python命令行程序上套一层GUI的壳!在GUI程序中,用subprocess以子进程的方式启动命令行程序,实时获取子进程的输出并在GUI中显示出来。不过有个问题,原命令行程序的print如果没有加flush=True参数怎么办?可以使用python命令行的-u参数!

如果subproc.py的代码是这样的,即print没有flush=True:

import time

while True:
    print('subprocess print...')
    time.sleep(1)

proc.py的代码修改如下,使用 -u 参数:

from subprocess import *

proc = Popen('python -u subproc.py', shell=True, stdout=PIPE, stderr=PIPE)
while True:
    rcode = proc.poll()
    if rcode is None:
        print('from subprocess: ', end='')
        line = proc.stdout.readline().strip()
        print(line.decode())

执行效果跟之前一样!

以上就是对实时获取子进程输出的技术介绍!

-- EOF --

本文链接:https://www.pynote.net/archives/1757

留言区

《实时获取subprocess子进程的输出》有1条留言

电子邮件地址不会被公开。 必填项已用*标注

  • 麦新杰

    proc.stdout.readline如果读不到内容,是阻塞的。 [回复]


前一篇:
后一篇:

More


©Copyright 麦新杰 Since 2019 Python笔记

go to top