来自 Python 子进程的实时输出/流

Dan*_*gel 12 python console subprocess stream

我正在使用 Python 及其子进程库来使用 strace 检查调用的输出,具体如下:

subprocess.check_output(["strace", str(processname)]) 
Run Code Online (Sandbox Code Playgroud)

但是,这只在被调用的子进程完成后才给我输出,这对我的用例来说非常有限。

我需要进程的一种“流”或实时输出,因此我需要在进程仍在运行读取输出,而不是仅在进程完成后读取输出。

有没有一种使用子流程库来实现此目的的便捷方法?我正在考虑每 x 秒进行一次轮询,但没有找到有关如何在文档中实现此功能的任何提示。

提前谢谢了。

Ste*_*ley 18

从 Python 3.2 开始(当添加了上下文管理器支持时Popen),我发现这是从子进程连续流输出的最直接的方法:

import subprocess


def run(args):
  with subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as process:
    for line in process.stdout:
      print(line.decode('utf8'))
Run Code Online (Sandbox Code Playgroud)


use*_*862 8

在引用测试运行程序的流输出的选定答案时遇到一些问题。以下对我来说效果更好:

import subprocess
from time import sleep

def stream_process(process):
    go = process.poll() is None
    for line in process.stdout:
        print(line)
    return go

process = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
while stream_process(process):
    sleep(0.1)
Run Code Online (Sandbox Code Playgroud)


kin*_*ian 5

根据文档

Popen.poll()

检查子进程是否已终止。设置并返回 returncode 属性。

所以基于此你可以:

process = subprocess.Popen('your_command_here',stdout=subprocess.PIPE)
while True:
    output = process.stdout.readline()
    if process.poll() is not None and output == '':
        break
    if output:
        print (output.strip())
retval = process.poll()
Run Code Online (Sandbox Code Playgroud)

这将循环读取标准输出,并实时显示输出。


这在当前版本的 python 中不起作用。(至少)对于 Python 3.8.5 及更高版本,您应该替换output == ''output == b''

  • 我猜自从你回答 b/c 后,子进程就发生了变化,我必须将 `... and output == ''` 更改为 `... and output == b''` 因为 `process.stdout.readline()`正在返回字节字符串。否则循环永远不会终止。 (6认同)