2010-08-11 147 views
1

我希望能夠使用Popen.communicate,並有標準輸出記錄到文件中(除了從communicate()返回通信的Python subprocess.Popen通過管道

此我想要做什麼 - 但真的是這樣嗎一個好主意?

cat_task = subprocess.Popen(["cat"], stdout=subprocess.PIPE, stdin=subprocess.PIPE) 
tee_task = subprocess.Popen(["tee", "-a", "/tmp/logcmd"], stdin=cat_task.stdout, 
    stdout = subprocess.PIPE, close_fds=True) 
cat_task.stdout = tee_task.stdout #since cat's stdout is consumed by tee, read from tee. 
cat_task.communicate("hello there") 
('hello there', None) 

與此有關的問題,尋找溝通的IMPL它看起來不錯,但有沒有更好的辦法?

回答

1

根據您的「更好」的定義,我要說的是,以下可能是在某種意義上說,它避免了額外的發球過程中更好:

import subprocess 

def logcommunicate(self, s): 
    std = self.oldcommunicate(s) 
    self.logfilehandle.write(std[0]) 
    return std 

subprocess.Popen.oldcommunicate = subprocess.Popen.communicate 
subprocess.Popen.communicate = logcommunicate 
logfh = open("/tmp/communicate.log", "a") 

proc = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE) 
proc.logfilehandle = logfh 

result = proc.communicate("hello there\n") 
print result 

簡而言之,它提供了communicate()包裝寫入標準輸出到您選擇的文件句柄,然後返回原來的元組爲您使用。我省略了異常處理;如果程序更關鍵,你應該補充一點。另外,如果您希望創建幾個對象並且希望它們全都登錄到同一個文件,那麼您應該安排logcommunicate()爲線程安全的(每個文件句柄同步)。您可以輕鬆擴展此解決方案以寫入stdout和stderr的單獨文件。

請注意,如果您希望來回傳遞大量數據,那麼communicate()可能不是最好的選擇,因爲它將內存中的所有內容都緩存起來。