2014-02-25 91 views
2

我正在使用python代碼啓動腳本。此代碼應啓動在磁盤上寫入文件的腳本,然後等待腳本完成。Popen有限緩衝區

但是,無論何時使用python啓動此腳本,結果文件不會超過65768字節,並且腳本不再響應。以下是我在python中使用的內容:

p = subprocess.Popen(command, 
        shell=True, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, 
        bufsize=-1) 
p.wait() 

其中command是腳本的命令。

有沒有人知道這個問題的解決方案?

謝謝。

+2

該腳本是否也迴應(如冗長的東西,如寫入文件的副本)到標準輸出?事實上,你並沒有閱讀孩子的標準輸出,所以如果它在某個時候變滿了,孩子將停止一切(掛在例如'print'語句上),包括寫入它的輸出文件。 – Tibo

+0

@OneOfOne:它不是重複的。這個問題不是關於'MemoryError';這是由於完整的管道緩衝區造成的死鎖。 – jfs

+0

如果你不需要子進程的標準輸出,那麼你可以將它重定向到devnull:'import os; DEVNULL = open(os.devnull,'wb'); subprocess.check_call([script],stdout = DEVNULL,stderr = STDOUT)' – jfs

回答

0
from time import sleep 
p = subprocess.Popen(command, 
        shell=True, 
        stdout=subprocess.PIPE, 
        stderr=subprocess.STDOUT, 
        bufsize=-1) 
output = '' 
while p.poll() is None: 
    output += p.stdout.readline()+'\n' # <--- This is your magic 
    sleep(0.025) 
output += p.stdout.read() # <--- And this is just to get the leftover data 
print('Command finished') 

p.stdout.close() 

爲@ J.F評論上幾乎每一個Popen答案我給,你不應該定義stdout=...stdin=...stderr=...,除非你打算utelize他們。 因爲他們會填滿緩衝區並掛起你的應用程序。

但是,如果你這樣做,確保你偶爾「輕點」它。

+0

使用'output = p.communicate()[0]'而不是'output ='''開始的行並且結束。丟棄輸出;你可以[使用'DEVNULL'](http://stackoverflow.com/questions/22014648/limited-buffer-in-popen#comment33383993_22014648)。 – jfs

+1

我記得應該用'None'來代替'== None'的評論。 – jfs

+0

@ J.F.Sebastian哈哈哈啊,老兄......老習慣和所有那些..(另外,不要對你的..我不學習,只是有些東西需要一段時間纔會落實到快速編碼的日常程序中) – Torxed