2014-12-30 86 views
1

最近我一直在搞Popen。我催生了輸出寫入TemporaryFile背景的過程:回調函數處理輸出

f = tempfile.TemporaryFile() 
p = subprocess.Popen(["gatttool"], stdin = subprocess.PIPE, stdout = f) 

現在它在我通過stdin發送命令到過程和讀了一下後臨時文件的方式。它是非阻塞的,所以我可以執行其他任務。

問題是,gatttool有時會生成一些輸出自身(例如通知)。我正在尋找一種方法來讀取此輸出,而不會阻止TemporaryFile

我的問題:

1)它是安全的讀取從TemporaryFile(50行輸出),並希望subprocess優雅地等待我來讀取數據或將其終止?

2)是否有一種優雅的方式來創建一個回調函數,該函數將在TemporaryFile上的每個事件上調用(而不是每秒運行一次並讀取數據的線程)?

+1

看起來像一個很好的用例命名管道(而不是純文本文件)。 –

+0

也許:https://docs.python.org/2.2/lib/os-fd-ops.html並使用簡單的pipe()? – Melon

+0

個人而言,我喜歡在'sh'模塊的子流程中使用更高級別的包裝 - 這就是爲什麼我發佈評論而不是編寫proprer答案的原因。 –

回答

0

其實分辨率很簡單。創建一個pipe,使用gatttool輸出作爲輸入。該管道的輸出爲thread,它逐行讀取該輸出並分析每一行。檢查它,它的工作原理。請鎖定此問題。

# Create a pipe. "gatt_in" ins where the "gatttool" will be dumping it's output. 
# We read that output from the other end of pipe, "gatt_out" 
gatt_out, gatt_in = os.pipe() 

gatt_process = subprocess.Popen(["gatttool", "your parametres"], stdin = subprocess.PIPE, 
           stdout = gatt_in) 

現在每次我想發出一個命令gatttool我這樣做:

gatt_process.stdin.write("Some commands\n") 

此命令的結果將在gatt_out apear。在我的情況下,這是在另一個線程處理。

+0

你的意思是'stdout = subprocess.PIPE'? – jfs

+0

你可以發佈你用來做這個的代碼嗎?我是一個Python N00b,我真的很感激看到這個代碼。我遇到了同樣的問題。 – dgangsta

+0

我會在早上發佈代碼的第一件事。 – Melon

0

提供輸入/得到一個子進程的輸出,你可以使用subprocess.PIPE

from subprocess import Popen, PIPE 

p = Popen(['gatttool', 'arg 1', 'arg 2'], stdin=PIPE, stdout=PIPE, bufsize=1) 
# provide input 
p.stdin.write(b'input data') 
p.stdin.close() 
# read output incrementally (in "real-time") 
for line in iter(p.stdout.readline, b''): 
    print line, 
p.stdout.close() 
p.wait() 
+0

使用'''PIPE'''作爲stdout將導致應用程序掛起。 '''gatttool'''不發送EOF,它只是坐在那裏。另外,在你的例子中,你只提供單行數據,而在我的應用程序中,我提供了一些輸入,並將輸出彙集到別處 – Melon

+0

@Melon:顯然,你可以寫多行(調用'p.stdin.write' ),並且不需要在同一個線程中讀取:您可以將讀取循環放入守護進程線程中,併爲每行/每個字節/任何您喜歡的地方調用回調。在內部,'subprocess'模塊可以使用'os.pipe()',這樣你就不需要自己調用它。 – jfs