gpt4 book ai didi

python - 需要一种更好的方法来从 python 执行控制台命令并记录结果

转载 作者:太空狗 更新时间:2023-10-30 02:06:47 27 4
gpt4 key购买 nike

我有一个 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 字符串后跟 :)。

最佳答案

如果您只想在文件中输出以供以后评估,则可以重定向到文件。

您已经通过 stdout=/stderr= 方法定义了您执行的进程的 stdout/stderr。

在您的示例代码中,您只是重定向到当前输出/错误分配的脚本。

subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

sys.stdout 和 sys.stderr 只是类文件对象。作为 sys.stdout 上的文档文档提到,“任何对象都是可以接受的,只要它有一个接受字符串参数的 write() 方法。”

f = open('cmd_fileoutput.txt', 'w')
subprocess.Popen(cmd, shell=True, stdout=f, stderr=f)

所以你只需要给它一个带有 write 方法的类来重定向输出。

如果你想要控制台输出和文件输出,可以创建一个类来管理输出。

一般重定向:

# Redirecting stdout and stderr to a file
f = open('log.txt', 'w')
sys.stdout = f
sys.stderr = f

制作重定向类:

# redirecting to both
class OutputManager:
def __init__(self, filename, console):
self.f = open(filename, 'w')
self.con = console

def write(self, data):
self.con.write(data)
self.f.write(data)

new_stdout = OutputManager("log.txt", sys.stdout)

交错依赖于缓冲,因此您可能会或可能不会得到您期望的输出。(您可能可以关闭或减少使用的缓冲,但我现在不记得是怎么做的)

关于python - 需要一种更好的方法来从 python 执行控制台命令并记录结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/559578/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com