我正在尝试使用 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,但是每次尝试似乎都会遇到同样的问题。看起来用于与子进程通信的管道在执行完成之前不会关闭。
大多数程序在连接到文件或管道时默认完全缓冲其标准输出流。当 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