2011-09-12 46 views
12

我可以在我的成功輸出重定向到一個文件,但是這似乎覆蓋該文件的現有數據:附加subprocess.Popen輸出到文件?

import subprocess 
outfile = open('test','w') #same with "w" or "a" as opening mode 
outfile.write('Hello') 
subprocess.Popen('ls',stdout=outfile) 

將刪除該文件的'Hello'線。我猜想一個解決方法是將輸出存儲爲其他字符串或其他東西(它不會太長),並將其與outfile.write(thestring)手動追加 - 但我想知道如果我在模塊中缺少一些便於使用的東西這個。

回答

12

您確定可以將subprocess.Popen的輸出附加到文件中,然後每天使用它。下面是我如何做到這一點:

log = open('some file.txt', 'a') # so that data written to it will be appended 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

(當然,這是,我沒有使用subprocess列出的文件...一個虛擬的例子)

順便說一句,與write()任何對象都可以更換這log項目,所以你可以緩衝輸出,並做任何你想要的(寫入文件,顯示等等)在這個文件類對象內。

注意:可能有誤導的是,subprocess,由於某種原因我不明白,會在之前寫之前的內容。所以,這裏是使用這種方式:

log = open('some file.txt', 'a') 
log.write('some text, as header of the file\n') 
log.flush() # <-- here's something not to forget! 
c = subprocess.Popen(['dir', '/p'], stdout=log, stderr=log, shell=True) 

所以提示的是:不要忘記flush輸出!

+0

注意對上述職位:有些試驗後,似乎'subprocess.Popen'需要一個類似於stdout和stderr參數的文件,所以僅用'write'方法給它們一個自定義對象是不夠的。我試過了,但是'fileno'函數是必需的,而且我還不夠好在我自己的類中模擬這個函數。 –

+2

我一直在試圖使用這種方法,但我發現,由於某種原因,每次我運行外部進程時都有一個我已經明確打開的文件來追加,進程的輸出從文件的開頭寫入並覆蓋那裏有任何信息。因此,要使用此解決方案,必須在打開文件後立即調用log.seek(0,os.SEEK_END)。 – Luke

0

文件中的數據是否真的被覆蓋?在我的Linux主機,我有以下行爲: 1)你的代碼執行在單獨的目錄獲取:

$ cat test 
test 
test.py 
test.py~ 
Hello 

2)如果我outfile.write('Hello')之後添加outfile.flush(),結果略有不同:

$ cat test 
Hello 
test 
test.py 
test.py~ 

但在這兩種情況下輸出文件都有Hello。沒有明確的flush()調用標準輸出緩衝區將在python進程終止時刷新。 問題在哪裏?

0

那麼問題是,如果你想報頭是頭,那麼你需要刷新輸出的其餘部分被寫入到文件之前:d