gpt4 book ai didi

python - 无法从正在运行的进程读取标准输出

转载 作者:行者123 更新时间:2023-12-01 05:43:41 24 4
gpt4 key购买 nike

我已经阅读并尝试了 8 种不同的方法来回答与此相关的几个问题。我在 python 中打开了一个进程,并且想要读取其输出,即使该进程尚未终止。该过程通常至少需要 1 分钟才能完成,或者直到发送中断为止。无论我如何尝试,我都无法让它读取输出。我知道我传递的命令和参数,因为当我将其更改为 subprocess.call(cmd, args) 时,它将所有内容打印到屏幕上。我还检查了该进程是否正在使用 ps -ax 运行。这是我正在尝试的示例(cat/dev/random 与我的项目无关):

proc = subprocess.Popen(["cat", "/dev/random"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Process started.")

这是我迄今为止尝试过但失败的方法:

for line in iter(p.stdout.readline, ''):
strLine = str(line).rstrip()
print(">>> " + strLine )
sys.stdout.flush()

还有

output, error = proc.communicate()
print output

还有

while proc.poll() is None:
print("Still waiting.")
print(proc.stdout.readline(1))

我尝试了更多解决方案,这些解决方案是此解决方案的变体,但没有运气。当使用 call 函数而不更改 stdout 时,所有内容都会正确打印到控制台。我做错了什么?

我使用的是 Python 2.6。

最佳答案

我将您的代码复制到一个完整的函数和文件中,添加了一项更改(repr)以避免打印更改终端标题等内容,给出:

import subprocess
import sys

def tst():
proc = subprocess.Popen(["cat", "/dev/random"],
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
print("Process started.")
for line in iter(p.stdout.readline, ''):
strLine = str(line).rstrip()
print(">>> " + repr(strLine))
sys.stdout.flush

tst()

(哎呀,看起来我的剪切和粘贴在 sys.stdout.flush 上删除了括号!不过在这种情况下无害)

立即运行会产生明显的错误:

Process started.
Traceback (most recent call last):
File "foo.py", line 13, in <module>
tst()
File "foo.py", line 8, in tst
for line in iter(p.stdout.readline, ''):
NameError: global name 'p' is not defined

解决这个问题(用 proc 替换 p),该示例可以工作,对于“工作”的某些定义:/dev/random 不会停止生成输出,因此它会运行永远。

中间的示例将是一个问题,因为 proc.communicate() 将读取进程的整个输出,该输出是无限的,因此(最终)会耗尽内存。 :-)

第三个示例运行良好。

如果你用其他东西替换 cat/dev/random ,你可能会发现 Unix/Linux 管道的一个更有趣但也许更烦人的方面:进程的 stdout 流通常是行缓冲的当且仅当如果它转到“交互式设备”(如终端窗口)。管道不是“交互式设备”,因此 stdout 是 block 缓冲的,除非相关命令覆盖它本身。这可能是我无法在这里重现问题的根源。

您可以通过使用伪 ttys 代替(或补充)Python 的 subprocess 模块来解决此问题。

关于python - 无法从正在运行的进程读取标准输出,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16805827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com