[英]Python subprocess hangs on interaction
我正在尝试编写一个我的世界服务器包装器,使我可以向它发送命令并接收输出。 最终,我将附加一个套接字接口,以便可以远程控制我的家庭服务器以重新启动/第二个命令/等等。
为此,我尝试使用python子进程模块启动服务器,然后发送命令并接收服务器的输出。 现在,我遇到了一个问题,我可以获取服务器的输出并将其反映到屏幕上,但是我发送给进程的第一个命令冻结了整个过程,因此我必须杀死它。 应该注意的是,我试图删除process.communicate行,而用print(command)代替。 这也冻结了过程。我非常基本的当前代码如下:
from subprocess import Popen, PIPE
from threading import Thread
import threading
def listen(process):
while process.poll() is None:
output = process.stdout.readline()
print(str(output))
def talk(process):
command = input("Enter command: ")
while command != "exit_wrapper":
#freezes on first send command
parse_command(process, command)
command = input("Enter command: ")
print("EXITTING! KILLING SERVER!")
process.kill()
def parse_command(process, command):
process.communicate(command.encode())
def main():
process = Popen("C:\\Minecraft Servers\\ServerStart.bat", cwd = "C:\\Minecraft Servers\\", stdout=PIPE, stdin=PIPE)
listener = Thread(None, listen, None, kwargs={'process':process})
listener.start()
talker = Thread(None, talk, None, kwargs={'process':process})
talker.start()
listener.join()
talker.join()
if __name__ == "__main__":
main()
提供的任何帮助将不胜感激!
subprocess.Popen.communicate()
文档明确指出:
与进程交互:将数据发送到stdin。 从stdout和stderr读取数据,直到到达文件末尾。 等待进程终止 。
在您的情况下,它正是这样做的。 您想要做的而不是等待流程终止的方法是与该流程进行交互,因此,就像您直接在listen()
函数中从STDOUT流中读取一样,您应该写入流程STDIN以便发送命令。 就像是:
def talk(process):
command = input("Enter command: ")
while command != "exit_wrapper" and process.poll() is None:
process.stdin.write(command) # write the command to the process STDIN
process.stdin.flush() # flush it
command = input("Enter command: ") # get the next command from user
if process.poll() is None:
print("EXITING! KILLING SERVER!")
process.kill()
但是,这种方法的问题在于,您可能会用Enter command:
提示符覆盖服务器的输出,并且用户最终将在服务器的输出上键入命令,而不是在输入的“提示”中输入指定的。
相反,您可能想做的是在listen()
函数中解析服务器的输出,然后根据收集的输出确定包装的服务器何时需要用户输入,然后才调用talk()
函数(当然,从中删除while循环)以获取用户输入。
如果Minecraft服务器试图通过它告诉您一些信息,您还应该同时输出STDERR。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.