在子进程执行期间读取stderr/stdout

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

我正在尝试使用 subprocces 库在 python 中运行命令并在执行过程中读取 stderr。

作为示例,我有以下 python 文件:

import time

if __name__ == "__main__":
    time.sleep(1)
    print("testing stdout")
    time.sleep(10)
    print("another msg")

我想要的是在整个程序完成执行之前读取打印的字符串。 我当前执行此操作的代码如下:

procId = subprocess.Popen('python3 teststuff.py', shell=True, close_fds=True, stdin =subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)

    line = procId.stdout.read()
    print(line)

这是可行的,但是在第一次睡眠 1 秒后不会收到输出,而是在整个程序执行后立即读取两条打印消息。是否有一种非阻塞方式来读取 stdout/stderr 流?

除了上面的代码之外,我已经尝试使用其他方法,例如使用 .communicate,但是每次尝试似乎都会遇到同样的问题。看起来用于与子进程通信的管道在执行完成之前不会关闭。

python io subprocess stdout stderr
1个回答
0
投票

大多数程序在连接到文件或管道时默认完全缓冲其标准输出流。当 stdout 连接到 tty 时,它们会对 stdout 进行行缓冲。您可以在不使用 Python 的

subprocess
模块的情况下看到这一点。打开两个 shell 会话。在第一次运行时

mkfifo p
cat < p

在第二次运行生成输出的程序:

python3 -c 'import time; print("line 1"); time.sleep(5); print("line 2")' >p

通过包含

-u
标志强制 Python 进程取消缓冲 stdout 来重复实验:

python3 -u -c 'import time; print("line 1"); time.sleep(5); print("line 2")' >p
© www.soinside.com 2019 - 2024. All rights reserved.