2012-05-15 118 views
2

我已經知道有幾個問題針對這個主題,但是他們都沒有解決我的具體問題。或者至少我找不到它。運行並從後臺進程獲得輸出

我需要在後臺執行一些程序,等待輸出並對其進行處理。 但後臺程序必須繼續執行

來自我需要的後臺程序的信息恰好位於其輸出的第二行。如果此程序阻止我的代碼直到到達此行,則不會有任何問題。但重要的是它在該行之後解鎖,以便我可以執行與後臺程序完全無關的其他任務。

不過,我不知道如何做到這一點。我已經閱讀了很多subprocess模塊的文檔,特別是subprocess.Popen

作爲實踐:爲什麼this code不適用於['localtunnel', '8000']論點?它不輸出任何...

我知道我不需要root權限來執行此操作。從jadkik94答案後


編輯和巨星

遺憾的是,答案並不爲我工作。也許我做錯了什麼...

首先。 A「健全檢查」:

Main thread... 
PING google.com (74.125.234.160) 56(84) bytes of data. 
64 bytes from plusone.google.com (74.125.234.160): icmp_req=1 ttl=54 time=82.5 ms 
Main thread... 
64 bytes from plusone.google.com (74.125.234.160): icmp_req=2 ttl=54 time=82.7 ms 
[...] 

但是,當我與args我想(args = ['localtunnel', 8000])使用它,唯一的輸出是Main thread...

import subprocess, threading, time 
can_break = False 

def run(): 
    args = ["ping", "google.com"] 
    popen = subprocess.Popen(args, shell=False, stdout=subprocess.PIPE) 
    while not can_break: 
     print popen.stdout.readline() 

t = threading.Thread(target=run) 

try: 
    t.start() 
    while True: 
     print 'Main thread...' 
     time.sleep(1) 
except KeyboardInterrupt: 
    can_break = True 

上面的代碼類似於此輸出工作正常。

當我在主線程(阻塞)調用localtunnel,它返回所需的輸出:

In [x]: popen = subprocess.Popen(['localtunnel', '8000']) 
    This localtunnel service is brought to you by Twilio. 
    Port 8000 is now publicly accessible from http://????.localtunnel.com ... 

這種方法是基於jadkik94的答案。但是,費斯特的答案也不起作用。

+0

需要明確的是:在Python腳本是否需要任何後臺程序的輸出超過第二行?還是隻需要讓它繼續運行? –

+0

第二行後,後臺程序可以「隱藏」其輸出。 – borges

回答

1

要以非阻塞的方式啓動程序,但仍然能夠看到程序的輸出,程序必須在單獨的線程或進程中啓動。瑞恩在這裏發表一個很好的示例代碼:Python Subprocess.Popen from a thread

請記住,它如何出現當時最後一行print myclass.stdout將打印輸出。如果程序剛啓動,它可能根本沒有輸出,所以你的代碼應該從myclass.stdout中讀取,直到它接收到你需要的行。

+0

請參閱我上面的編輯。 – borges

1

你可以在一個線程中運行它(這樣它不會阻止你的代碼運行),並獲得輸出,直到獲得第二行,然後等待它終止。這是一個例子,它將讀取Windows上命令dir /s的輸出以獲取所有目錄列表。

import subprocess, thread, time 

def run(): 
    global can_break 

    args = ["dir", "/s"] 
    shell = True 

    count = 0 
    popen = subprocess.Popen(args, shell=shell, stdout=subprocess.PIPE) 
    while True: 
     line = popen.stdout.readline() 
     if line == "": continue 
     count += 1 
     if count == 2: 
      do_something_with(line) 
      break 

    print "We got our line, we are waiting now" 
    popen.wait() 
    print "Done." 
    can_break = True 

def do_something_with(line): 
    print '>>> This is it:', line 

thread.start_new_thread(run, tuple()) 

can_break = False 
while not can_break: 
    print 'Wait' 
    time.sleep(1) 

print 'Okay!' 

輸出如下:

 
Wait 
>>> This is it: Volume Serial Number is XXXX-XXXX 

We got our line, we are waiting now 
Wait 
Wait 
Wait 
. 
. 
. 
Done. 
Wait 
Okay! 
+0

請看看我上面的編輯。 – borges

+0

看來你對1)它在一個線程中運行的事實(我們有問題)2)你傳遞給'subprocess.Popen'的參數有問題。所以試着在一個線程中運行它,就像你在主函數中運行一樣:'subprocess.Popen(args)' – jadkik94

+0

還有一件事情:帶有新行或不帶有參數的args輸出是「Main Thread ...」?應該有大量的新行,因爲'popen.stdout.readline()'應該返回一些東西......並且你正在打印它。我會試着讓'localtunnel'在這裏運行,然後自己看看。 – jadkik94

相關問題