python中stdin.write,python子进程多个stdin.write和stdout.read

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

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

And if I replace test.py with a standard linux command like 'cat', things work as expected.

Is there any way I send multiple stdin writes and read multiple stdout back?

解决方案

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).

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='')

Note:

sys.exectable is the current python executable (Python 3 in this case)

universal_newlines=True enables the text mode (otherwise, cat.stdin and cat.stdout work with bytes, not strings)

the with-statement closes the pipes and waits for the child process to exit.

And here's the corresponding 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)

Output

enter something...hello, world!

enter something...and another line

enter something...

Note: there is no new line after "enter something..."

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='')

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).

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值