Python subprocess.stdout.readline()挂起

时间:2014-12-03 16:28:52

标签: python-2.7 subprocess

我在python上使用subprocess尝试简单的代码,而调用process.stdout.readline()时它会挂起。如何解决这个问题呢?在输出中尝试fcntl for nonblock时,我得到了空白输出。

我的源代码:

from subprocess import Popen,PIPE 
import fcntl
import os

proc = Popen(['./test'],stdin=PIPE,stdout=PIPE) 

fcntl.fcntl(proc.stdout.fileno(), fcntl.F_SETFL, os.O_NONBLOCK)

print "Started!"

print proc.stdout.readline()

proc.stdin.write('5\n')
proc.stdin.flush()

print proc.stdout.readline()

proc.stdin.write('5\n')
proc.stdin.flush()


print proc.stdout.readline()
proc.stdout.close()
proc.stdin.close()

输出应该是这样的:

First number: 5
Second number: 5
Answer: 10

1 个答案:

答案 0 :(得分:0)

您想要的输出表明First number:之后没有换行符,因此阻塞proc.stdout.readline()调用(proc.stdin.write('5\n')行之前)挂起且非阻塞变量返回任何内容(空字节字符串) - - 还没有新行/ EOF返回。

要解决此问题,您可以在提示结束时(在冒号':'处)停止阅读。见subprocess readline hangs waiting for EOF

即使提示后有换行符;由于缓冲问题,readline()可能会挂起。见Python C program subprocess hangs at "for line in iter"

例如,如果test等同于:

#!/usr/bin/env python3
a = int(input('First number: '))
b = int(input('Second number: '))
print('Answer:', a + b)

然后得到答案,你可以使用pexpect module

#!/usr/bin/env python
import pexpect # $ pip install pexpect

def print_result(locals):
    result = int(locals['child'].after.rpartition(b' ')[2])
    print(result)

pexpect.run('./test', events={'First number': '5\n', 'Second number': '5\n',
                              r'Answer:\s*\d+': print_result})

如果你想看到输入和输出;你可以设置logfile=sys.stdout参数。