我正在尝试通过Python 2.7运行一个Minecraft服务器,它运行正常。 但是当我尝试将stop命令传递给它时,它在服务器输出内容之前不会执行任何操作。
这是我的代码:
import os, sys, subprocess, threading, time
class Server:
def start(self):
t = threading.Thread(target=self.run)
t.daemon = True
t.start()
def run(self):
self.p = subprocess.Popen('java -Xmx512M -Xms512M -jar minecraft_server.1.8.1.jar nogui',
cwd=os.path.join(os.getcwd(), 'server'),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
while True:
nextline = self.p.stdout.readline()
print self.p.poll()
if nextline == '' and self.p.poll() != None:
break
if not nextline == '':
sys.stdout.write(nextline)
sys.stdout.flush()
def stop(self):
self.p.communicate(input='stop')[0]
#endclass
s = Server()
s.start()
count = 0
# keep running
while True:
count += 1
if count == 15:
s.stop()
print "STOPPING SERVER"
time.sleep(1)
输出图片: 我想让它不要停在那里。
15秒后停止测试是否可以让它正常工作,但我不知道如何解决这个问题。我看到一些使用'fcntl'的解决方案,但我希望这可以在所有平台上运行,因此对我来说不是一个选项。
我怎样才能这样做,以便我可以随时运行任何命令?
更新
import os, sys, subprocess, threading, time
class Server:
def start(self):
t = threading.Thread(target=self.run)
t.daemon = True
t.start()
def run(self):
self.p = subprocess.Popen('java -Xmx512M -Xms512M -jar minecraft_server.1.8.1.jar nogui',
cwd=os.path.join(os.getcwd(), 'server'),
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
shell=True)
print "started server"
while True:
outs, errs = self.p.communicate(input=None)
print outs.decode()
print "TEST"
def stop(self):
self.p.stdin.write('stop')
#endclass
s = Server()
s.start()
count = 0
# keep running
while True:
count += 1
print count
if count == 15:
s.stop()
print "STOPPING SERVER"
time.sleep(1)
输出图片:
答案 0 :(得分:1)
这里有很多问题:
.communicate()
和.stdout.readline()
的调用,这些调用都试图从stdout读取。虽然这些都不是严格非法,但两者都是非常不可取的,并导致像这样的问题。
我建议让一个线程监视器stdout / stderr(带.communicate(input=None)
),另一个手动说话stdin(带.stdin.write()
或类似)。