python子进程多个stdin.write和stdout.read [英] python subprocess multiple stdin.write and stdout.read
问题描述
感谢您抽出时间回答问题.我正在使用Python 3.4,并且有两个简单的python程序.一个是一个名为test.py的程序,它需要用户输入并打印出一些东西.
Thanks for taking time to answer the question. I am playing around with Python 3.4 and I have two simple python programs. One, a program called test.py that takes a user input and prints something.
while True:
print("enter something...")
x = input()
print(x)
time.sleep(1)
要向该程序发送输入,我还有另一个使用子进程的程序:
To send input to this program, I have another program that uses subprocess:
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())
但是,当我运行上述程序时,出现错误:
However when I run the above program, I get an error:
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,一切都会按预期进行.
And if I replace test.py with a standard linux command like 'cat', things work as expected.
我可以通过多种方式发送多个stdin写入并读取多个stdout吗?
Is there any way I send multiple stdin writes and read multiple stdout back?
推荐答案
通常,您应该对交互程序使用pexpect
(基于对话框的交互).
In general, you should use pexpect
for interactive programs (dialog-based interactions).
您的特定问题可能是由python版本不匹配引起的(您认为您的代码是使用Python 3执行的,而实际上可能是使用Python 2执行的).预期第二个问题(EOFError
):要么在子脚本中捕获它,要么提供一个让孩子退出的信号(我在下面的代码示例中使用空行).
Your specific issue might be caused by a python version mismatch (you think your code is executed using Python 3 while actually it might be executed using Python 2). The second issue (EOFError
) is expected: either catch it in the child script or provide a signal for the child to exit (I use an empty line for that in the code example below).
这是一个Python 3代码,在Python 2上大声失败
Here's a Python 3 code that fails loudly on 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
语句关闭管道并等待子进程退出.
sys.exectable
is the current python executable (Python 3 in this case)universal_newlines=True
enables the text mode (otherwise,cat.stdin
andcat.stdout
work with bytes, not strings)-u
makes the child's output line-buffered (otherwise, you won't see anything until the child flushes its internal stdout buffer)- the
with
-statement closes the pipes and waits for the child process to exit.
这是对应的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..."
它可以工作,但很脆弱,请阅读问:为什么不只使用管道(popen())?和改用pexpect
.
It works but it is fragile, read Q: Why not just use a pipe (popen())? and use pexpect
instead.
如果输入是有限的,并且不依赖于输出,则可以一次全部传递它:
If the input is finite and it doesn't depend on the output then you could pass it all at once:
#!/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:
This version requires that the child handles EOF properly:
#!/usr/bin/env python3
import time
while True:
try:
x = input("enter something...")
except EOFError:
break # no more input
print(x)
time.sleep(1)
输出相同(如上所示).
The output is the same (as shown above).
这篇关于python子进程多个stdin.write和stdout.read的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!