proc.communicate()
等待子流程完成,因此最多可以使用它
一旦
你可以通过
全部的
立即输入,并在子进程退出后获取所有输出。
如果不修改输入/输出,则不需要重定向子进程的stdin/stdout。
要将输入馈送到后台线程中的子进程,并在其逐行到达时立即打印其输出,请执行以下操作:
#!/usr/bin/env python3
import errno
from io import TextIOWrapper
from subprocess import Popen, PIPE
from threading import Thread
def feed(pipe):
while True:
try: # get input
line = input('Enter input for minecraft')
except EOFError:
break # no more input
else:
# ... do something with `line` here
# feed input to pipe
try:
print(line, file=pipe)
except BrokenPipeError:
break # can't write to pipe anymore
except OSError as e:
if e.errno == errno.EINVAL:
break # same as EPIPE on Windows
else:
raise # allow the error to propagate
try:
pipe.close() # inform subprocess -- no more input
except OSError:
pass # ignore
with Popen(["java", "-jar", "minecraft_server.jar"],
cwd=r'C:\Users\Derek\Desktop\server',
stdin=PIPE, stdout=PIPE, bufsize=1) as p, \
TextIOWrapper(p.stdin, encoding='utf-8',
write_through=True, line_buffering=True) as text_input:
Thread(target=feed, args=[text_input], daemon=True).start()
for line in TextIOWrapper(p.stdout, encoding='utf-8'):
# ... do something with `line` here
print(line, end='')
关于的说明
p.stdin
:
-
print()
在每个
line
。这是必要的,因为
input()
去掉换行符
-
p.stdin.flush()
在每行之后调用(
line_buffering=True
)
minecraft的输出可能会延迟,直到其标准输出缓冲区被刷新。
如果您对
“做点什么
线
此处“
注释不会重定向相应的管道(暂时忽略字符编码问题)。
TextIOWrapper
默认情况下使用通用换行模式。具体说明
newline
如果您不希望,请显式指定参数。