问题描述
感谢您抽出宝贵时间回答问题。 我正在使用Python 3.4,并且有两个简单的python程序。 一种是名为test.py的程序,该程序需要用户输入并打印某些内容。
while True:
print("enter something...")
x = input()
print(x)
time.sleep(1)
要将输入发送到该程序,我还有另一个使用子进程的程序:
from subprocess import Popen, PIPE
cat = Popen('python test.py', shell=True, stdin=PIPE, stdout=PIPE)
cat.stdin.write("hello, world!\n")
cat.stdin.flush()
print(cat.stdout.readline())
cat.stdin.write("and another line\n")
cat.stdin.flush()
print(cat.stdout.readline())
但是,当我运行上述程序时,出现错误:
enter something...
hello, world!
Traceback (most recent call last):
File "/opt/test.py", line 9, in <module>
x = input()
EOFError: EOF when reading a line
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe
而且,如果我用“ cat”之类的标准linux命令替换了test.py,一切都会按预期进行。
有什么办法可以发送多个stdin写入并读回多个stdout?
1楼
通常,应将 。
您的特定问题可能是由python版本不匹配引起的(您认为您的代码是使用Python 3执行的,而实际上可能是使用Python 2执行的)。
第二个问题( EOFError
)是预期的:要么在子脚本中捕获它,要么提供一个让孩子退出的信号(在下面的代码示例中,我使用空行)。
这是一个Python 3代码,在Python 2上大声失败:
#!/usr/bin/env python3
import sys
from subprocess import Popen, PIPE
with Popen([sys.executable, '-u', 'test.py'], stdin=PIPE, stdout=PIPE,
universal_newlines=True, bufsize=1) as cat:
for input_string in ["hello, world!", "and another line", ""]:
print(input_string, file=cat.stdin, flush=True)
print(cat.stdout.readline(), end='')
注意:
-
sys.exectable
是当前的python可执行文件(在这种情况下为Python 3) -
universal_newlines=True
启用文本模式(否则,cat.stdin
和cat.stdout
使用字节而不是字符串) -
-u
使孩子的输出行缓冲( ) -
with
-statement关闭管道并等待子进程退出。
这是相应的test.py
:
#!/usr/bin/env python3
import time
while True:
x = input("enter something...")
if not x: # exit if the input is empty
break
print(x)
time.sleep(1)
产量
enter something...hello, world!
enter something...and another line
enter something...
注意: "enter something..."
后没有新行
它可以工作,但很脆弱,请阅读 并 。
如果输入是有限的并且不依赖于输出,则可以一次全部传递:
#!/usr/bin/env python3
import sys
from subprocess import check_output
output = check_output([sys.executable, 'test.py'],
input="\n".join(["hello, world!", "and another line"]),
universal_newlines=True)
print(output, end='')
此版本要求孩子正确处理EOF:
#!/usr/bin/env python3
import time
while True:
try:
x = input("enter something...")
except EOFError:
break # no more input
print(x)
time.sleep(1)
输出是相同的(如上所示)。