读取子进程的stdout,同时将其保存在缓冲区中。

问题描述 投票:0回答:1

是否可以读取子进程的 stdout 但在程序结束时仍然保持整个 process.communicate()?

例如,我有一个python脚本,它在一个应用程序中启动一个c#应用程序。Popen 子进程,并实时检查它产生的日志文件,以确定它所处的状态,但某些错误并没有被转储到日志中,而是在 stdout 和某些错误会导致进程挂起。我希望能够检测到这些输出,并在这些情况下能够杀死该进程。

这很容易,在做 process.stdout.readline() 但在程序结束时,我失去了以原生格式转储整个stdout的能力,因为缓冲区在读取后会被刷新。有没有可能保留那个缓冲区?

或者至少把读到的行以它的原始格式保存在一个变量中?

python subprocess popen
1个回答
1
投票

你可以逐行读取stdout,进行处理并保存到一个列表或缓冲区中,以后可以使用缓冲区。在这个例子中,处理只是 print但你可以随心所欲地改变它。我还以为你只是想在后台收集stderr,所以单独创建了一个线程。

import subprocess as subp
import threading
import io

def _pipe_read_thread(stream, output):
    output.write(stream.read())
    stream.close()

def proc_runner(cmd):
    stdout_lines = []
    stdout_buf = io.BytesIO()
    stderr_buf = io.BytesIO()
    p = subp.Popen(cmd, stdout=subp.PIPE, stderr=subp.PIPE)
    stderr_t = threading.Thread(target=_pipe_read_thread,
        args=(p.stderr, stderr_buf))
    stderr_t.start()
    for line in p.stdout:
        print(line)
        stdout_buf.write(line)
    returncode = p.wait()
    stderr_t.join()
    stdout_buf. seek(0)
    stderr_buf.seek(0)
    return returncode, stdout_buf, stderr_buf

returncode, stdout, stderr = proc_runner(['ls', '-a'])
print('=============================')
print(stdout.read())
print('=============================')
print(stderr.read())
© www.soinside.com 2019 - 2024. All rights reserved.