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

Python 无法从正在运行的进程中读取标准输出,python,process,Python,Process,我已经阅读并尝试了8种不同的方法,回答了有关这方面的几个问题。我用python打开了一个进程,希望读取它的输出,即使进程还没有终止。该过程通常至少在1分钟内或在发送中断之前不会完成。无论我尝试什么,我都无法让它读取输出。我知道我传递的命令和参数是有效的,因为当我将其更改为subprocess.call(cmd,args)时,它会将所有内容打印到屏幕上。我还检查了进程是否使用ps-ax运行。下面是我正在尝试的示例(cat/dev/random与我的项目无关): 以下是我迄今为止失败的尝试: for

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

以下是我迄今为止失败的尝试:

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

我尝试过更多的解决方案,它们都是这方面的变体,但没有运气。在不更改标准输出的情况下使用调用函数时,所有内容都会正确打印到控制台。我做错了什么


我使用的是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
进程已启动。
回溯(最近一次呼叫最后一次):
文件“foo.py”,第13行,在
tst()
tst中第8行的文件“foo.py”
对于iter中的线路(p.stdout.readline“”):
NameError:未定义全局名称“p”
修正了这一点(将
p
替换为
proc
),对于“works”的某些定义,该示例是有效的:/dev/random不会停止生成输出,因此它将永远运行

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

第三个例子很好用

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


您可以通过使用伪ttys来解决这个问题,而不是(或除了)Python的
子流程
模块。

您的流程是否实际将其输出发送到
stdout
而不是
stderr
?你们检查过了吗?谢谢,猫工作了,但我的工具还挂着。我在你关于pty的回答中使用了这个建议,并找到了一个有帮助的链接:。接受你的回答,谢谢。
while proc.poll() is None:
    print("Still waiting.")
    print(proc.stdout.readline(1))
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()
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