Python与子进程输入管道
我有一个小脚本,它每半小时会给一个Java程序(游戏服务器管理器)发送一个命令,就像用户在输入一样。不过,我看了文档和试了几次,还是搞不清楚怎么实现两个功能:
1) 我想要一个版本,让用户可以在终端窗口里输入命令,这些命令会像“save-all”命令一样发送到服务器管理器。
2) 我想要一个版本,它可以一直运行,但能把任何新输入直接发送到系统里,这样就不需要第二个终端窗口了。现在这个功能其实有点实现了,因为当输入内容时,虽然没有视觉反馈,但一旦程序结束,就能看到终端收到了输入。例如,如果在程序运行时输入了“dir”,结束后会看到目录内容。这一部分更多是为了理解,而不是实用。
谢谢你的帮助。以下是脚本:
from time import sleep
import sys,os
import subprocess
# Launches the server with specified parameters, waits however
# long is specified in saveInterval, then saves the map.
# Edit the value after "saveInterval =" to desired number of minutes.
# Default is 30
saveInterval = 30
# Start the server. Substitute the launch command with whatever you please.
p = subprocess.Popen('java -Xmx1024M -Xms1024M -jar minecraft_server.jar',
shell=False,
stdin=subprocess.PIPE);
while(True):
sleep(saveInterval*60)
# Comment out these two lines if you want the save to happen silently.
p.stdin.write("say Backing up map...\n")
p.stdin.flush()
# Stop all other saves to prevent corruption.
p.stdin.write("save-off\n")
p.stdin.flush()
sleep(1)
# Perform save
p.stdin.write("save-all\n")
p.stdin.flush()
sleep(10)
# Allow other saves again.
p.stdin.write("save-on\n")
p.stdin.flush()
3 个回答
1
这可能不能完全解决你的问题,但你可以试试Python的cmd模块。这个模块可以帮助你轻松地实现一个可扩展的命令行循环(通常叫做REPL)。
1
你可以用一个叫做“screen”的工具来运行程序,这样你就可以把输入发送到特定的屏幕会话,而不是直接发送给程序。如果你是在Windows系统上,只需要安装一个叫做cygwin的工具就可以了。
2
把你的 sleep()
替换成调用 select((sys.stdin, ), (), (), saveInterval*60)
-- 这样做的效果是一样的,都是有个超时设置,但它会监听用户在标准输入(stdin)上的命令。当 select
告诉你有输入时,就从 sys.stdin 读取一行内容,并把它传给你的程序。当 select
指出超时时,就执行你现在正在做的“保存”命令。