我有一个.jar文件,我通过Popen
使用参数运行。此服务器启动大约需要4秒钟,然后在终端上转储“Server Started”,然后运行直到用户退出终端。但是,print
和webbrowser.open
由于Popen
而立即执行,如果我使用call
,则它们根本不会运行。有没有办法确保print
和webbrowser
在服务器启动之后才运行,而不是使用wait
?也许grep for server启动了?
from subprocess import Popen
import glob
import sys
import webbrowser
reasoner = glob.glob("reasoner*.jar")
reasoner = reasoner.pop()
port = str(input("Enter connection port: "))
space = ""
portArg = ("-p", port)
portArg = space.join(portArg)
print "Navigate to the Reasoner at http://locahost:" + port
reasoner_process = Popen(["java", "-jar", reasoner, "-i", "0.0.0.0", portArg, "--dbconnect", "jdbc:h2:tcp://localhost//tmp/UXDemo;user=sa;password=admin"])
# I want the following to execute after the .jar process above
print "Opening http://locahost:" + port + "..."
webbrowser.open("http://locahost:" + port)
答案 0 :(得分:2)
您要做的是与CLI应用程序交互的非常简单,特殊的版本。所以,你有两个选择。
首先,您可以使用像pexpect
这样的库,它可以处理几乎任何CLI应用程序。它可能有点过分,并且有一点学习曲线,但是一旦你掌握了基础知识,这将使你的问题变得微不足道:你启动JAR,阻止期望“服务器启动”,然后关闭。
或者,您可以使用Popen
管道手动执行此操作。一般来说这有很多问题,但是当你知道有一个输出很容易适合128个字节并且你不想做任何事情而只是阻塞那个输出然后关闭管道时,这些问题都没有出现起来。所以:
reasoner_process = Popen(args, stdout=PIPE)
line = reasoner_process.stdout.readline()
if line.strip() != 'Server Started':
# error handling
# Any code that you want to do while the server is running goes here
reasoner_process.stdout.close()
reasoner_process.kill()
reasoner_process.wait()
但首先要确保你真的要杀了它;通常关闭管道就足够了,在这种情况下你可以而且应该省略kill()
,在这种情况下你也可以检查退出代码,如果它不是0则提高。
此外,您可能需要with contextlib.closing(…)
或其他任何适当的内容,或只需要try
/ finally
,以确保您可以引发错误处理异常而不会泄漏孩子。 (Python 3.2+使这更简单,因为它保证管道和Popen
本身都可用作上下文管理器。)
最后,我假设“运行直到用户退出终端”意味着你要等待它启动,然后在你做其他事情时让它继续运行,然后杀死它。如果您的工作流程不同,您显然需要更改执行操作的顺序。