python子进程挂起读取管道

时间:2013-08-09 18:18:19

标签: python

我有这个,但最后从管道读取的子进程挂起:

$cat waitforinput.sh
#!/bin/sh


while read line
do
echo $line
done                    


>>> p1 = subprocess.Popen(["/home/abc/waitforinput.sh", "-v"], shell=True, executable=None,stdin=subprocess.PIPE, stdout=subprocess.PIPE)
>>> 
>>> 
>>> p1.stdin.write('This is a good idea\n')
>>> p1.stdin.write('This is a good idea\n')
>>> p1.stdin.write('This is a good idea\n')
>>> p1.stdin.write('This is a good idea\n')
>>> p1.stdin.write('This is a good idea\n')
>>> 
>>> 
>>> p1.stdin.flush()
>>> 
>>> for i in p1.stdout:
...     print i 
... 

我该怎么办才能不挂?

2 个答案:

答案 0 :(得分:3)

而不是flush(),请致电p1.stdin.close()

...
p1.stdin.write('This is good idea\n')
p1.stdin.write('This is good idea\n')

p1.stdin.close()

for i in p1.stdout:
    print i

<强>更新

stdout-iteration替换为 while循环使用stdout.readline()

参考python联机帮助页-u部分:

  

强制stdin,stdout和stderr完全无缓冲。上   重要的系统,也把stdin,stdout和stderr放进去   二进制模式。请注意,xread中有内部缓冲 -   lines(),readlines()和file-object迭代器(“for line in   sys.stdin“)不受此选项的影响。工作   围绕这个,你会想在里面使用“sys.stdin.readline()”   一个“while 1:”循环。

p1.stdin.flush()

while True:
    line = p1.stdout.readline()
    if not line:
        break
    print line

您将获得输出,但如果没有close(),脚本将不会结束。无论如何,你应该使用close()

答案 1 :(得分:1)

问题是waitforinput.sh正在缓冲其输出。 falsetru的解决方案有效,因为close会导致脚本退出并刷新其输出缓冲区。这是处理流水线命令的常用方法。

如果您想以交互方式输出输出,可以使用pty模块或pexpect来欺骗脚本,使其认为它正在写入终端。然后,它的输出将只是行缓冲。