为了账号安全,请及时绑定邮箱和手机立即绑定

读取子进程标准输出,同时将其保存在缓冲区中

读取子进程标准输出,同时将其保存在缓冲区中

梦里花落0921 2022-12-20 11:01:09
是否可以读取子进程stdout但在程序结束时仍然保持整体process.communicate()?例如,我有一个 python 脚本,它在Popen子进程中启动 ac# app,并实时检查它生成的日志文件以确定它所处的状态,但某些错误不会转储到日志中,而是在其中,stdout并且某些错误会导致进程挂起。我希望能够检测到该输出,并且在那些情况下能够终止该进程。这在做的时候很容易,process.stdout.readline()但在程序结束时,我失去了以其本机格式转储整个标准输出的能力,因为缓冲区在读取后被刷新。是否可以维护该缓冲区?或者至少将读取的行以其本机格式保存在变量中?
查看完整描述

1 回答

?
慕沐林林

TA贡献2016条经验 获得超9个赞

您可以逐行读取标准输出,对其进行处理并将其保存到列表或缓冲区中,并在以后使用缓冲区。在此示例中,处理只是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())


查看完整回答
反对 回复 2022-12-20
  • 1 回答
  • 0 关注
  • 90 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信