Python subprocess.call()为每个stdout和stderr行添加前缀

Python subprocess.call()为每个stdout和stderr行添加前缀,python,datetime,logging,subprocess,stdout,Python,Datetime,Logging,Subprocess,Stdout,我正在使用python运行一些shell脚本、RScript、python程序等。这些程序可能会运行很长时间,并且可能会向stdout和stderr输出大量(日志)信息。我正在使用以下(Python 2.6)代码,这些代码运行良好: stdoutFile=open('stdout.txt', 'a') stderrFile=open('stderr.txt', 'a') subprocess.call(SHELL_COMMAND, shell=True, stdout=stdoutFile, s

我正在使用python运行一些shell脚本、RScript、python程序等。这些程序可能会运行很长时间,并且可能会向stdout和stderr输出大量(日志)信息。我正在使用以下(Python 2.6)代码,这些代码运行良好:

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

注意:修改我运行的程序不是一个选项,因为python代码有点像这些程序的包装器。

直接创建
Popen
对象并创建
管道,而不是向
subprocess.call()的
stdout
stderr
参数提供文件,然后在这个管理器脚本中读取这些管道,并在写入任何日志文件之前,预先添加任何您想要的标记

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()
阻塞,直到子进程退出。您可能希望直接使用子流程的流,以便进行更多的实时日志记录,但是您必须自己处理并发和缓冲区填充状态。

我认为第二个选项不起作用,因为它们缺少用于(直接)写入的
.fileno()
方法。不过第一个是+1。啊,很有趣,看起来你是对的。我将删除第二位。