无法从正在运行的进程中读取stdout

时间:2013-05-29 05:00:27

标签: 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。

1 个答案:

答案 0 :(得分:2)

我将您的代码复制到一个完整的函数和文件中,添加了一个更改(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

修复(将p替换为proc),该示例有效,对于“works”的某些定义:/ dev / random不会停止生成输出,因此它会永远运行。

中间的例子将是一个问题,因为proc.communicate()将读取进程的整个输出,这是无限的,因此将使你失去内存(最终)。 : - )

第三个例子工作正常。

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

您可以使用伪ttys而不是(或除了)Python的subprocess模块来解决此问题。