确保Python中的命令顺序

时间:2014-09-23 18:31:23

标签: python concurrency jar

我有一个.jar文件,我通过Popen使用参数运行。此服务器启动大约需要4秒钟,然后在终端上转储“Server Started”,然后运行直到用户退出终端。但是,printwebbrowser.open由于Popen而立即执行,如果我使用call,则它们根本不会运行。有没有办法确保printwebbrowser在服务器启动之后才运行,而不是使用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)

1 个答案:

答案 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本身都可用作上下文管理器。)

最后,我假设“运行直到用户退出终端”意味着你要等待它启动,然后在你做其他事情时让它继续运行,然后杀死它。如果您的工作流程不同,您显然需要更改执行操作的顺序。