2012-05-25 198 views
2

我正在編寫一個將使用子進程的Python腳本。主要想法是有一個運行專用子腳本的父腳本,例如,運行其他程序或自己做一些東西。父腳本和子流程之間有管道。我用它們通過定期發送一些字符並檢查響應來控制子進程是否仍在響應。問題是,當子進程在屏幕上打印任何東西(即寫入stdout或stderr)時,管道被破壞,一切都崩潰。所以我的主要問題是是否可以在子進程中阻止寫入std *,因此只有寫入管道的合法響應纔有可能?我已經嘗試Stop a function from writing to stdout但沒有任何成功。阻止寫入標準輸出

還歡迎其他想法父母和子過程之間的溝通(除基於文件的管道)。但是,必須使用子進程。

回答

0

可以傳遞一個函數來subprocess.Popen被之前執行請求的程序來執行:

def close_std(): 
    os.close(0) 
    os.close(1) 
    os.close(2) 

p = subprocess.Popen(cmd, preexec_fn=close_std) 

注意使用低級別os.close的;關閉sys.std*只會在分叉的Python進程中起作用。另外,請注意,如果您的底層程序是Python腳本,那麼當它們嘗試寫入關閉的文件描述符時,它們可能會因爲異常而死亡。

+0

它們是Python腳本,完全發生在你寫的東西上。但是,仍然感謝你的想法和時間。 – user1192062

+0

@ user1192062:你爲什麼不把子進程的stdout和stderr連接到管道上? –

1

我堅信,你不只是不得不接受「當屏幕上的子打印任何東西(即寫到標準輸出或標準錯誤),管道破裂和崩潰的一切」。你可以解決這個問題。那麼你不需要「阻止」從寫入到標準流的子流程。

正確使用子過程模塊的所有功能。首先,一個subprocess.PIPE連接到每一個子進程的標準流:

p = subprocess.Popen(
     [executable, arg1, arg2], 
     stdin=subprocess.PIPE, 
     stdout=subprocess.PIPE, 
     stderr=subprocess.PIPE) 

運行的子進程,並通過這些管道與它進行交互:

stdout, stderr = p.communicate(stdin="command") 

如果communicate()不夠靈活(如您需要同時監控多個子進程和/或如果某個子進程的stdin數據取決於其輸出以響應前一個命令),則可以直接與p.stdout,p.stderr,屬性進行交互。在這種情況下,您可能需要建立自己的監控迴路並使用p.poll()和/或p.returncode。控制子過程也可以通過p.send_signal()來實現。

相關問題