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

标签 python process

我已经阅读并尝试了 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/

相关文章:

python - 使用 python 的 BigQuery 外部表

javascript - 如何使用 spawn 在 Node js 中暂停进程

c# - 如何在 C# 中最大化我的应用程序使用的功率?

linux - 我如何附加到正在运行的进程,如 Linux 上的调试器?

c - 如何在没有外部机制的情况下通信树的进程

python - 如果 RAM 接近饱和,如何终止 Python 进程(Windows 上的 Anaconda)?

python - 为什么我的简单线性模型在数据集 g(X) 上学习阈值函数 f(x) = (x > 0) 但在 X 上表现不佳?

python - GPU 上的 Tensorflow matmul 计算比 CPU 上慢

python - NetBox 安装期间出错,无法使用 manage.py 创建 super 用户

python - 使用 Django 模型中的 URLField 链接到外部站点