我有一个Python脚本,需要执行几个命令行工具。stdout输出有时会用于进一步处理。在所有情况下,我都想记录结果并在检测到错误时引发异常。为此,我使用以下函数:
def execute(cmd, logsink):
logsink.log("executing: %s\n" % cmd)
popen_obj = subprocess.Popen(\
cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
(stdout, stderr) = popen_obj.communicate()
returncode = popen_obj.returncode
if (returncode <> 0):
logsink.log(" RETURN CODE: %s\n" % str(returncode))
if (len(stdout.strip()) > 0):
logsink.log(" STDOUT:\n%s\n" % stdout)
if (len(stderr.strip()) > 0):
logsink.log(" STDERR:\n%s\n" % stderr)
if (returncode <> 0):
raise Exception, "execute failed with error output:\n%s" % stderr
return stdout
"logsink"可以是任何具有日志方法的Python对象。我通常使用它将日志数据转发到特定文件、回显到控制台、同时执行两者或其他操作...
这个方法非常有效,但存在三个问题,我需要比communicate()提供更细粒度的控制:
1.在控制台上,stdout和stderr输出可能会交错,但上述函数会将它们分开记录。这可能会使日志的解释变得复杂。如何记录stdout和stderr行,按照它们输出的顺序交错记录? 2.上述函数只会在命令完成后记录命令输出。当命令陷入无限循环或因其他原因需要很长时间时,这会使问题的诊断变得复杂。如何在命令仍在执行时实时获取日志? 3.如果日志很大,很难解释哪个命令生成了哪个输出。是否有一种方法可以在每行前加上某些内容(例如cmd字符串的第一个单词后跟:)?