为什么我不能从通过Python脚本调用的进程中获取输出?

时间:2015-03-21 13:42:36

标签: python linux process

基于此 Stackoverflow问题,我试图通过Python获取进程的输出。

这里有代码:

from subprocess import Popen, PIPE

connection_string = "yowsup-cli demos --yowsup --config config"
popen_parameters = connection_string.split(" ")
proc = Popen(popen_parameters, stdout=PIPE, stderr=PIPE)

while True:
    line = proc.stdout.readline()

    if line != '':
        #the real code does filtering here
        print "Result:", line.rstrip()

    proc.stdout.flush()

不幸的是没有回复。顺便说一句,我需要与发送和接收数据的过程进行交互。我怎么能这样做?

谢谢!

2 个答案:

答案 0 :(得分:1)

即使在发送命令的输出之后,while循环也没有条件退出。 试试这个:

if line != '':
    #the real code does filtering here
    print "Result:", line.rstrip()
else:
    break

答案 1 :(得分:1)

首先,如果子进程实际写入其stdout,则代码应该。如果命令中有错误,则输出可能会显示在stderr上。

请注意,您的代码不会退出循环,因此您需要修复它,例如通过在读取空字符串时调用break

但还有更好的方法。不要直接阅读子进程'stdout,而是使用Popen.communicate()

from subprocess import Popen, PIPE

connection_string = "yowsup-cli demos --yowsup --config config"
popen_parameters = connection_string.split(" ")
proc = Popen(popen_parameters, stdout=PIPE, stderr=PIPE)

out, err = proc.communicate()
if out:
    print "Received stdout output of length {} from child process".format(len(out))
    print out
elif err:
    print "Received stderr output of length {} from child process".format(len(err))
    print err

您的问题的另一部分涉及与子进程的交互。在简单的情况下,您启动子进程并向其发送单个输入,您仍然可以通过向其传递字符串参数来使用Popen.communicate()。请注意,您还需要设置stdin管道。所以,如上所述:

proc = Popen(popen_parameters, stdin=PIPE, stdout=PIPE, stderr=PIPE)

data = 'data to send to child'
out, err = proc.communicate(data)

如果您与孩子的互动更复杂,您应该考虑使用专为此用途设计的pexpect模块。虽然可以使用Popen()来执行此操作,但是在读取/写入管道的过程中存在缓冲和死锁的一些问题,因此最好避免这种情况。