当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《需要一种更好的方法从python执行控制台命令并记录结果》经验,为你挑选了1个好方法。

我有一个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对象.我通常使用它来将日志记录数据转发到特定文件,或将其回显到控制台,或两者,或其他...

这非常好,除了三个问题,我需要更多细粒度控制而不是communication()方法提供:

    stdout和stderr输出可以在控制台上交错,但上面的函数会单独记录它们.这可能使日志的解释复杂化.如何以与输出顺序相同的顺序记录stdout和stderr行的交错?

    上述功能仅在命令完成后记录命令输出.当命令陷入无限循环或由于某些其他原因需要很长时间时,这会使问题的诊断变得复杂.如何在命令仍在执行的同时实时获取日志?

    如果日志很大,则很难解释哪个命令生成了哪个输出.有没有办法为每行添加一些东西(例如cmd字符串的第一个单词后跟:).

monkut.. 5

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

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

在您的示例代码中,您只需重定向到脚本当前out/err分配.

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)

交错取决于缓冲,因此您可能会或可能不会得到您期望的输出.(您可以关闭或减少使用的缓冲,但我不记得此刻的情况)



1> monkut..:

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

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

在您的示例代码中,您只需重定向到脚本当前out/err分配.

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)

交错取决于缓冲,因此您可能会或可能不会得到您期望的输出.(您可以关闭或减少使用的缓冲,但我不记得此刻的情况)

推荐阅读
牛尾巴2010
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有