如何将子进程命令的错误消息保存到文件

新手上路,请多包涵

使用子进程运行 bash 命令时,我可能会遇到命令无效的情况。在这种情况下,bash 将返回一条错误消息。我们怎样才能捕捉到这条消息呢?我想将此消息保存到日志文件中。以下是一个示例,我尝试在不存在的目录中列出文件。

 try:
    subprocess.check_call(["ls", "/home/non"])
    df = subprocess.Popen(["ls", "/home/non"], stdout=subprocess.PIPE)
    output, err = df.communicate()
    # process outputs
except Exception as error:
    print error
    sys.exit(1)

Bash 会打印“ls:无法访问/home/non:没有这样的文件或目录”。我怎样才能得到这个错误信息? except 行捕获的错误明显不同,它说“Command ‘[‘ls’, ‘/home/non’]’ returned non-zero exit status 2”。

原文由 Luke 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

您可以将 stderr 重定向到一个文件对象:

 from subprocess import PIPE, CalledProcessError, check_call, Popen

with open("log.txt", "w") as f:
    try:
        check_call(["ls", "/home/non"], stderr=f)
        df = Popen(["ls", "/home/non"], stdout=PIPE)
        output, err = df.communicate()
    except CalledProcessError as e:
        print(e)
        exit(1)

输出到log.txt:

 ls: cannot access /home/non: No such file or directory

如果您想要消息除外:

 try:
    check_call(["ls", "/home/non"])
    df = Popen(["ls", "/home/non"], stdout=PIPE)
    output, err = df.communicate()
except CalledProcessError as e:
    print(e.message)

对于 python 2.6, e.message 将不起作用。您可以使用 python 2.7 的类似版本 check_output 将适用于 python 2.6:

 from subprocess import PIPE, CalledProcessError, Popen

def check_output(*args, **kwargs):
    process = Popen(stdout=PIPE, *args, **kwargs)
    out, err = process.communicate()
    ret = process.poll()
    if ret:
        cmd = kwargs.get("args")
        if cmd is None:
            cmd = args[0]
        error = CalledProcessError(ret, cmd)
        error.out = out
        error.message = err
        raise error
    return out

try:
    out = check_output(["ls", "/home"], stderr=PIPE)
    df = Popen(["ls", "/home/non"], stdout=PIPE)
    output, err = df.communicate()
except CalledProcessError as e:
    print(e.message)
else:
    print(out)

原文由 Padraic Cunningham 发布,翻译遵循 CC BY-SA 3.0 许可协议

“ls: cannot access /home/non: No such file or directory” 是由 ls 命令生成的, 而不是 bash 生成的。

如果您想使用异常处理来处理不存在的文件,请使用 subprocess.check_output()

 #!/usr/bin/env python
from subprocess import check_output, STDOUT, CalledProcessError

try:
    output = check_output(['ls', 'nonexistent'], stderr=STDOUT)
except CalledProcessError as exc:
    print(exc.output)
else:
    assert 0

输出

ls: cannot access nonexistent: No such file or directory

原文由 jfs 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题