2015-01-06 106 views
0

我有一個python腳本,我正在調用另一個使用子進程的腳本,如下所示。捕捉python子進程異常

 sp = subprocess.Popen("script.py --arg1 --arg2', cwd=GIVEN_PATH, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 

     while sp.poll() is None: 
      for out in iter(sp.stdout.readline,''): 
       self.log(out.rstrip()) 

這工作正常,但我想從script.py得到任何異常。我知道我們可以得到retcode,但我實際上需要獲取完整的例外信息。

如果script.py提高

  raise IOERROR("got an exception") 

然後我需要知道這個信息。 simailar方式我們得到sys.exc_info()等

有沒有辦法我可以做到這一點?

由於提前

+0

除了下面的答案之外,有必要指出的是,Python可以直接調用其他python模塊,而不需要子進程,這將允許您捕獲異常。這是你在這種情況下應該做的。 – VooDooNOFX

回答

1

不,你不能從一個子進程得到sys.exc_info() - 通過你能看到的返回碼,時間對象在內存中(包括堆棧跟蹤)的子進程已經走了。

您可以通過爲stderr輸出提供一個單獨的管道並讀取該文件來解析您的子進程寫入stderr的文本。假設你的程序不會寫入標準錯誤,否則將在該流中顯示的唯一文本將是錯誤消息和堆棧跟蹤。

但是,您會希望對此方法持謹慎態度,因爲如果進程將更多文本寫入stderr而不是緩衝區,則會導致死鎖。最好的解決方案是有一個單獨的線程同時讀取stdout和stderr。

0

如果你想得到sys.exc_info()那麼你可以導入模塊並運行它的功能,而不是使用subprocess模塊。如果需要在不同的進程中運行,則可以使用multiprocessing模塊。

另一種可能性是使用execfile()在與父腳本相同的過程中將模塊作爲腳本運行。如果您想將命令行參數傳遞給腳本,則可以在調用execfile()之前操作sys.argv全局列表。

或者你可以結合subprocess + execfile方法:編寫使用execfile運行孩子腳本和序列化的所有異常包裝腳本(例如,使用pickle)和父腳本中使用subprocess運行包裝腳本。分別捕獲stderr,以便能夠解除孩子的異常信息。

+0

謝謝。唯一的問題是我需要運行帶有參數的python文件,這個文件在execfile() – user2891472

+0

@ user2891472上看不到:我已經更新了答案,提到如何將命令行參數傳遞給使用'execfile( )' – jfs