开发Minecraft服务器面板:如何提前获取运行脚本的输出?
实时获取Minecraft服务器脚本输出的解决方案
你的问题核心是要后台启动进程并实时抓取输出,当前用communicate()的方式要么等进程结束,要么超时返回,没法拿到过程中的实时输出,这里给你两个实用的解决方法:
方法1:行缓冲逐行读取
通过设置Popen的缓冲模式,让脚本输出一行就读取一行,不用等进程结束:
import subprocess # 启动进程,配置行缓冲+自动解码 server_process = subprocess.Popen( "./start.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, # 把错误输出合并到标准输出,方便统一处理 bufsize=1, # 启用行缓冲 text=True # 自动将字节流转成字符串,替代旧的universal_newlines=True ) def get_realtime_output(): # 逐行读取输出,进程运行时会持续返回内容 for line in server_process.stdout: yield line.rstrip('\n') # 去掉换行符,按需调整 # 示例:实时打印输出 for output in get_realtime_output(): print(output)
注意事项:
- 如果你的
start.sh在非终端环境下输出是块缓冲(比如没有TTY时),可能需要修改脚本启动方式,用stdbuf -oL强制行缓冲:server_process = subprocess.Popen( ["stdbuf", "-oL", "./start.sh"], # 这里不用shell=True更安全 stdout=subprocess.PIPE, stderr=subprocess.STDOUT, bufsize=1, text=True )
方法2:非阻塞读取(适合多任务场景)
如果你的面板需要同时处理其他操作(比如接收用户输入给服务器发指令),可以用select模块实现非阻塞读取,避免主线程被卡住:
import subprocess import select server_process = subprocess.Popen( "./start.sh", shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, stdin=subprocess.PIPE, # 允许给进程发送输入(比如Minecraft指令) text=True ) # 持续监听进程输出直到进程结束 while server_process.poll() is None: # 检查stdout是否有可读内容,超时1秒避免一直阻塞 ready_streams, _, _ = select.select([server_process.stdout], [], [], 1) if ready_streams: line = server_process.stdout.readline() if line: print(line.strip()) # 进程结束后读取剩余输出 remaining_output = server_process.stdout.read() if remaining_output: print(remaining_output.strip())
扩展:给服务器发指令
如果需要在面板里给Minecraft服务器发送指令(比如stop),可以通过stdin写入:
server_process.stdin.write("stop\n") server_process.stdin.flush() # 必须刷新缓冲区才能让进程收到指令
内容的提问来源于stack exchange,提问作者ICE_Plane
相关产品推荐
相关产品推荐

