2017-05-19 32 views
1

在這裏有很多事情在少量的代碼。我會盡量保持簡潔。Python函數捕獲子進程標準輸出和標準錯誤日誌文件

我有一個python函數,它運行一個外部程序,並將stdout和stderr都指向一個日誌文件。

我使用doctest來測試函數。我需要測試輸出捕捉功能。下面的代碼顯示了我編寫函數和測試的嘗試。測試失敗,沒有寫入日誌文件。我不確定問題出在測試或測試代碼中,或者兩者兼而有之。建議?

from __future__ import print_function 

import subprocess 

def run(command_line, log_file): 
    """ 
    # Verify stdout and stderr are both written to log file in chronological order 
    >>> run("echo text to stdout; echo text to stderr 1>&2", "log") 
    >>> f = open("log"); out = f.read(); f.close() 
    >>> print(out.strip()) 
    text to stdout 
    text to stderr 
    """ 
    command_line = "set -o pipefail; " + command_line + " 2>&1 | tee " + log_file 

    # Run command. Wait for command to complete. If the return code was zero then return, otherwise raise CalledProcessError 
    subprocess.check_call(command_line, shell=True, executable="bash") 

測試結果:

$ python -m doctest testclass.py 
text to stdout 
text to stderr 
********************************************************************** 
File "testclass.py", line 10, in testclass.run 
Failed example: 
    print(out.strip()) 
Expected: 
    text to stdout 
    text to stderr 
Got: 
    <BLANKLINE> 
********************************************************************** 
1 items had failures: 
    1 of 3 in testclass.run 
***Test Failed*** 1 failures. 
+0

你嘗試,從產生的bash命令'「set -o pipefail;」+ command_line +「2>&1 | tee」 + log_file'在終端?輸出是什麼樣的? –

+0

發送到終端的文本與此命令一樣:set -o pipefail;將文本回顯到stdout;將文本回顯到stderr 1>&2 2>&1 | tee log – Steve

+0

@ Jean-FrançoisFabre這是大批量生產過程中的一小部分,用於生成用戶檢查處理結果所需的大型日誌文件。 – Steve

回答

2

既然做了subprocess.check_callshell=True,2標準輸出/標準錯誤重定向和tee不執行命令和捕捉輸出的最佳方式(實際上它是最接近到最糟糕的的方式),我不是真的很驚訝,它失敗了。

我的解決方案是刪除set -o pipefail初學者(你不需要在這裏檢查返回代碼)並將兩個命令都包含在括號中,否則重定向/ tee只適用於最後一個(我仍然困惑你爲什麼得不到任何輸出人所有的,說實話,雖然):

command_line = "(" + command_line + ") 2>&1 | tee " + log_file 

如果你不得不恢復pipefail事情,括號內做到這一點:

command_line = "(set -o pipefail; " + command_line + ") 2>&1 | tee " + log_file 
+0

我認爲他根本沒有輸出,因爲他實際上只是將'stderr'文本輸送到日誌文件,而這可能只是空的。 –

+0

@ThomasKühn,但他正在'echo stderr 1&2'的文本:應該發送文本到stderr。 –

+1

對,我錯過了那部分。沒有例子,這很難測試。那麼現在就解決了;) –

相關問題