2014-09-23 38 views
0

我有一個.jar文件,我用Popen的參數運行。該服務器需要大約4秒鐘的時間啓動,然後在終端上輸出「Server Started」,然後運行,直到用戶退出終端。然而,printwebbrowser.open由於Popen立即執行,如果我使用call,他們永遠不會運行。有沒有辦法確保printwebbrowser在服務器啓動之前不會運行,除非使用wait而不是?也許grep的服務器啓動?確保Python命令的順序

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) 

回答

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

最後,我假設「運行直到用戶退出終端」意味着你想要等待它開始,然後在你做其他事情時讓它繼續運行,然後殺死它。如果你的工作流程不同,你顯然需要改變你做事的順序。