2012-12-18 67 views
3

我正在使用python來運行一些shell腳本,RScripts,python程序等。這些程序可能會運行很長時間,可能會輸出很多(日誌記錄) info到stdout和stderr。我使用以下(Python 2.6中)代碼的正常工作:Python subprocess.call()爲每個stdout和stderr行添加前綴

stdoutFile=open('stdout.txt', 'a') 
stderrFile=open('stderr.txt', 'a') 
subprocess.call(SHELL_COMMAND, shell=True, stdout=stdoutFile, stderr=stderrFile) 
stdoutFile.close() 
stderrFile.close() 

這主要是記錄信息是轉到文件,並可以在很長一段時間來產生這個信息。因此,我想知道是否可以在每一行前加上日期和時間?

例如,如果我將當前登錄:

Started 
Part A done 
Part B done 
Finished 

那我想它是:

[2012-12-18 10:44:23] Started 
[2012-12-18 12:26:23] Part A done 
[2012-12-18 14:01:56] Part B done 
[2012-12-18 22:59:01] Finished 

注:修改,我運行的程序不和的選擇,因爲這條巨蟒代碼有點像這些程序的包裝。

回答

3

而是提供文件的subprocess.call()stdoutstderr論點,直接創建Popen對象,並創建PIPE s,則寫入任何日誌文件之前讀出在此管理腳本,並在前面加上你想要的任何標籤的管你想。

def flush_streams_to_logs(proc, stdout_log, stderr_log): 
    pipe_data = proc.communicate() 
    for data, log in zip(pipe_data, (stdout_log, stderr_log)): 
        # Add whatever extra text you want on each logged message here 
        log.write(str(data) + '\n') 

with open('stdout.txt', 'a') as stdout_log, open('stderr.txt', 'a') as stderr_log: 
    proc = subprocess.Popen(SHELL_COMMAND, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    while proc.returncode is None: 
     flush_streams_to_logs(proc, stdout_log, stderr_log) 
    flush_streams_to_logs(proc, stdout_log, stderr_log) 

請注意,communicate()阻塞,直到子進程退出。您可能希望直接使用子流程的流,以便您擁有更多的實時日誌記錄,但是您必須自己處理併發和緩衝區填充狀態。

+0

我不認爲第二個選項有效,因爲它們缺少用於(直接)寫入的'.fileno()'方法。儘管如此,第一個+1。 – glglgl

+0

啊,有趣,看起來你是對的。我會刪除第二位。 –