2017-07-04 63 views
1

我在Python中調用一個shell腳本fom,它產生了多個子進程。如果兩分鐘後未完成,我想終止該過程及其所有子項。在subprocess.TimeoutExpired後拋出Python子進程的子節點拋出

有沒有什麼辦法可以做到與subprocess.run或我必須回去使用Popen?由於運行阻塞,我無法將pid保存在某個地方,以額外的命令殺死孩子。一個簡短的代碼示例:

try: 
    subprocess.run(["my_shell_script"], stderr=subprocess.STDOUT, timeout=120) 
except subprocess.TimeoutExpired:                  
    print("Timeout during execution") 
+1

是,'popen'是首選。請注意,殺死孩子的孩子不是必須的(取決於'my_shell_script')。他們可以分離。 – freakish

+0

在我的情況下,我絕對希望他們遇難,因爲他們產生很高的負載。我可能會回覆使用Popen併爲我的進程獲得一個pid以殺死進程組。 – Raptor

回答

0

從文檔報價:

subprocess.run - 這不捕獲標準輸出或默認標準錯誤。爲此,請將PIPE傳遞給stdout和/或stderr參數。

如果您不想使用Popen(),則不必使用Popen()。模塊中的其他功能,例如.call(),.Popen()。

有三個'文件'流:stdin用於輸入,stdout和stderr用於輸出。應用程序決定在哪裏寫什麼;通常將錯誤和診斷信息標記爲stderr,其餘標記爲stdout。要捕獲這些輸出中的任何一個的輸出,請指定subprocess.PIPE參數,以便將'流'重定向到您的程序中。

超時後殺子過程:

import os 
import signal 
import subprocess 

try: 
    proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE, timeout=120) 
except subprocess.TimeoutExpired: 
    os.kill(proc.pid, signal.SIGTERM) 
+0

但是,這是如何幫助我殺死子進程的子進程呢?正如您在示例中所看到的,我已經捕獲了stderr。 – Raptor

+0

在答案中編輯。 – Tanu

+0

但不稱爲進程組。在這種情況下'proc.terminate()'更便攜(windows) –