在Python3中是否有一种从subprocess.run流式传输和捕获输出的方法?

在Python3中是否有一种从subprocess.run流式传输和捕获输出的方法?,python,python-3.x,subprocess,Python,Python 3.x,Subprocess,如果你这样做 subprocess.run(["echo hi && sleep 60"], shell=True, capture_output=False, timeout=5) 您将看到“hi”打印到终端,然后由于超时而引发异常 但如果你这样做了 ret = subprocess.run(["echo hi && sleep 6"], capture_output=True, timeout=2, shell=True) 您将看不到任何输出,超时异常将(

如果你这样做

subprocess.run(["echo hi && sleep 60"], shell=True, capture_output=False, timeout=5)
您将看到“hi”打印到终端,然后由于超时而引发异常

但如果你这样做了

ret = subprocess.run(["echo hi && sleep 6"], capture_output=True, timeout=2, shell=True)
您将看不到任何输出,超时异常将(据我所知)阻止您获取生成的输出。(对于这个例子,
shell=True
并不重要,我只是需要一种方便的方法使其超时。)

这会导致以下问题:I(a)需要获取命令的输出,但(b)有时无意中运行挂起等待用户输入的命令。我真的希望能够捕获在抛出超时异常的情况下生成的任何输出,或者将输出流式传输到stdout/stderr,同时也获取它的副本。

本身包括任何捕获的输出作为属性(
stdout
stderr
),因此:

当相关命令在超时之前实际写入管道时,将起作用

但是,如果子进程在完成之前被终止,而它仍然在用户模式缓冲区中有数据(它是块缓冲,或行缓冲,从来没有写过换行符或其他东西),它将永远不会被写入实际的管道,因此您将看不到它


解除子进程的缓冲有许多不同的方式,因此我无法给出具体的信息,说明如何在您的实际案例中执行(
echo
显然只是一个占位符),当无法修改子可执行文件以使其具有行缓冲或无缓冲时,
stdbuf
通常很有用。

您能否澄清两个示例之间的相关差异?(1) 您分配的返回值(2)将
sleep
从60更改为6(3)
capture\u output
False
更改为
True
(4)
timeout
从5更改为2(5)
?如果能看到两个只改变一件事的例子就好了。
try:
    ret = subprocess.run("commands go here && sleep 6", capture_output=True, timeout=2, shell=True)
except subprocess.TimeoutExpired as e:
    print(e.stdout)
else:
    print(ret.stdout)