2013-05-29 65 views
1

我已阅读并尝试了8种不同的方法来解答有关此问题的几个问题。我用python打开了一个进程,并且想要读取它的输出,即使这个进程还没有结束。该过程通常不会持续至少1分钟或直到发送中断。无论我尝试什么,我都无法读取输出结果。我知道我通过工作的命令和参数,因为当我将其更改为subprocess.call(cmd,args)时,它会将所有内容打印到屏幕上。我也检查过程是用ps -ax运行的。下面是我想要一个例子(猫的/ dev /随机无关我的项目):无法从正在运行的进程读取标准输出

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)) 

我尝试过的更多解决方案是这种变体,但没有运气。在不改变标准输出的情况下使用调用函数时,所有东西都可以正确输出到控制台。我究竟做错了什么?

我正在使用Python 2.6。

+0

你的程序是否真的把它的输出发送到'stdout'而不是'stderr'?你检查了吗? –

回答

1

我复制你的代码到一个完整的功能和文件,添加一个变化(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 

˚F ixing(替换pproc),该示例适用于“作品”的某些定义:/ dev/random不会停止生成输出以便永久运行。

中间示例将会出现问题,因为proc.communicate()将读取进程的整个输出,这是无限的,因此会使您的内存不足(最终)。 :-)

第三个例子工作正常。

如果将cat /dev/random替换为其他内容,您可能会发现Unix/Linux管道的一个更有趣或可能令人讨厌的方面:进程的stdout流通常是线性缓冲,当且仅当它转到“交互式设备”时像终端窗口)。管道不是“交互式设备”,所以标准输出是块缓冲的,除非有问题的命令会覆盖它本身。这可能是我在这里无法复制的问题的根源。

您可以使用伪-ttys来代替Python的subprocess模块(或除此之外)来解决此问题。

+0

谢谢,猫工作,但我的工具仍悬挂。我在你的关于pty的回答中使用了这个建议,并找到了一个帮助它的链接:[link](http://stackoverflow.com/questions/12419198/python-subprocess-readlines-hangs)。接受你的回答,谢谢。 – OldFart

相关问题