我有一个简单的python3脚本test.py
:
print('Test')
while True:
inp = input('> ')
print(input)
当我尝试使用subprocess.Popen
运行它并获取其输出时,它冻结:
from subprocess import Popen, PIPE
p = Popen(['python3', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)
print(p.stdout.read())
因此,我没有从该脚本获得任何输出。我尝试使用communicate
并以某种方式起作用:
p.communicate()[0]
但是我仍然需要使管道式标准输出正常工作。从脚本获取输出的第一个示例怎么了?
UPD:communicate
显示test.py
中有一个例外:第4行的input
上的EOF。为什么?如何与此类脚本进行互动?
答案 0 :(得分:0)
您没有输入任何标准输入,因此您自然会在第4行获得EOFError
,这是input
到达EOF时引发的异常。但是,即使您输入一些输入,由于它具有无限循环,它最终将消耗所有输入并最终引发EOFError
。您应该捕获异常并正常结束脚本。
此外,您在第5行有一个错字,您希望在其中打印inp
,而不是input
。
最后,您应该始终使用communicate
而不是直接从stdout
读取或直接写入stdin
。
警告::使用
communicate()
而不是.stdin.write
,.stdout.read
或.stderr.read
以避免死锁,因为其他OS管道缓冲区中的任何一个被填满并阻止子进程。
更正了test.py
:
print('Test')
while True:
try:
inp = input('> ')
except EOFError:
print 'Done'
break
print(inp)
与test.py
进行交互的正确方法:
>>> from subprocess import Popen, PIPE
>>> p = Popen(['python', 'test.py'], stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=False)
>>> p.communicate('hello\nworld\n')
('Test\n> hello\n> world\n> Done\n', '')
>>>