我有一个进程可以在命令行上进行通信,如下所示:
% process -
input
^D^D
output
所以:我开始这个过程,键入一些输入,然后按两次Ctrl-D后,我得到了输出。 我想围绕这个过程制作一个Python包装器。我创造了这个:
from subprocess import Popen, PIPE
p = Popen('process -', stdin=PIPE, stdout=PIPE, stderr=PIPE, shell=True)
while True:
input = raw_input('Enter input: ')
p.stdin.write(input)
p.stdin.close()
p.wait()
output = p.stdout.read()
print output
这是第一次有效,但之后我得到了:
Traceback (most recent call last):
File "test.py", line 7, in <module>
p.stdin.write(input)
ValueError: I/O operation on closed file
是否有其他方式可以在不关闭文件的情况下与此流程进行交互?
答案 0 :(得分:0)
p.wait()
将等到子流程退出之前退出,因此在脚本的第二次迭代中,p
已经退出(因此已关闭p.stdin
)。
答案 1 :(得分:0)
如果你的包裹过程在第一次输出后结束,则通讯将失败到第二次。由于所有管道(stdin和stdout)将被关闭。因此错误:
ValueError: I/O operation on closed file
。
每次尝试向包装过程发送输入时,都必须预期必须打开输入和管道。
另一方面,托马斯在答案中说,p.wait()
不是重复输入/输出策略的方法。
由于内部调用subprocess.Popen.communicate(),因此您无法使用subprocess.Popen.wait()。
您可以尝试使用p.stdin.write
和p.stdout.read
这里有一篇关于这个主题的好文章:Writing to a python subprocess pipe
答案 2 :(得分:0)
模拟shell会话:
$ process -
input
^D^D
output
在Python中,使用check_output()
:
#!/usr/bin/env python3
from subprocess import check_output
out = check_output(['process', '-'], input='input\n', universal_newlines=True)
print(out, end='')
Ctrl + D 被Unix终端($ stty -a
- 识别为EOF(终止输入) - 在输出中查找eof = ^D
和icanon
)。如果您需要输入 Ctrl + D 两次(at the beginning of a line);它可能表示process
计划中存在错误,例如"for line in sys.stdin:
doesn't notice EOF
the first time" Python bug。