proc.communicate()等待子进程完成,因此最多只能使用 一次 –您可以 一次 传递 所有 输入,并在子进程退出后获取所有输出。
如果不修改输入/输出,则无需重定向子流程的stdin / stdout。
要将输入馈送到后台线程中的子流程,并在一行一行到达时立即打印其输出:
#!/usr/bin/env python3import errnofrom io import TextIOWrapperfrom subprocess import Popen, PIPEfrom threading import Threaddef 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 # ignorewith Popen(["java", "-jar", "minecraft_server.jar"],cwd=r'C:UsersDerekDesktopserver',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
)之后被调用
我的世界的输出可能会延迟到刷新其标准输出缓冲区。
如果您在 _“
line在此处执行某些操作”_注释周围没有可添加的内容,请不要重定向相应的管道(暂时忽略字符编码问题)。
TextIOWrapper默认情况下使用通用换行模式。
newline如果不想,请明确指定参数。



