运行子进程并将输出打印到日志记录 [英] Run subprocess and print output to logging

查看:25
本文介绍了运行子进程并将输出打印到日志记录的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在寻找从 python 调用 shell 脚本并使用日志记录将它们的 stdout 和 stderr 写入文件的方法.这是我的代码:

I am looking for the way to call shell scripts from python and write their stdout and stderr to file using logging. Here is my code:

import logging
import tempfile
import shlex
import os

def run_shell_command(command_line):
    command_line_args = shlex.split(command_line)

    logging.info('Subprocess: "' + command_line + '"')

    process_succeeded = True
    try:
        process_output_filename = tempfile.mktemp(suffix = 'subprocess_tmp_file_')
        process_output = open(process_output_filename, 'w')

        command_line_process = subprocess.Popen(command_line_args,
                                                stdout = process_output,
                                                stderr = process_output)
        command_line_process.wait()
        process_output.close()

        process_output = open(process_output_filename, 'r')
        log_subprocess_output(process_output)
        process_output.close()

        os.remove(process_output_filename)
    except:
        exception = sys.exc_info()[1]
        logging.info('Exception occured: ' + str(exception))
        process_succeeded = False

    if process_succeeded:
        logging.info('Subprocess finished')
    else:
        logging.info('Subprocess failed')

    return process_succeeded

而且我确信有一种方法可以在不创建临时文件来存储进程输出的情况下做到这一点.有什么想法吗?

And I am sure that there is the way to do it without creating temporary file to store process output. Any ideas?

推荐答案

我确信有一种方法可以在不创建临时用于存储进程输出的文件

I am sure that there is the way to do it without creating temporary file to store process output

您只需检查 Popen 的文档,特别是stdoutstderr:

You simply have to check for the documentation of Popen, in particular about stdout and stderr:

stdinstdoutstderr 指定执行程序的标准输入、标准输出和标准错误文件句柄,分别.有效值为 PIPE,一个现有的文件描述符(一个正整数)、一个现有的文件对象和 None.PIPE 表示一个应该创建到孩子的新管道.使用默认设置None,不会发生重定向;孩子的文件句柄将是从父母那里继承.另外,stderr 可以是 STDOUT,这表明来自子进程的 stderr 数据应该被捕获到与 stdout 相同的文件句柄中.

stdin, stdout and stderr specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values are PIPE, an existing file descriptor (a positive integer), an existing file object, and None. PIPE indicates that a new pipe to the child should be created. With the default settings of None, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally, stderr can be STDOUT, which indicates that the stderr data from the child process should be captured into the same file handle as for stdout.

所以你可以看到你可以使用文件对象,也可以使用 PIPE 值.这允许您使用 communicate()检索输出的方法:

So you can see that you can either use a file object, or the PIPE value. This allows you to use the communicate() method to retrieve the output:

from StringIO import StringIO
process = subprocess.Popen(arguments, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
output, error = process.communicate()
log_subprocess_output(StringIO(output))

<小时>

我会将您的代码重写为:


I'd rewrite your code as:

import shlex
import logging
import subprocess
from StringIO import StringIO

def run_shell_command(command_line):
    command_line_args = shlex.split(command_line)

    logging.info('Subprocess: "' + command_line + '"')

    try:
        command_line_process = subprocess.Popen(
            command_line_args,
            stdout=subprocess.PIPE,
            stderr=subprocess.STDOUT,
        )

        process_output, _ =  command_line_process.communicate()

        # process_output is now a string, not a file,
        # you may want to do:
        # process_output = StringIO(process_output)
        log_subprocess_output(process_output)
    except (OSError, CalledProcessError) as exception:
        logging.info('Exception occured: ' + str(exception))
        logging.info('Subprocess failed')
        return False
    else:
        # no exception was raised
        logging.info('Subprocess finished')

    return True

这篇关于运行子进程并将输出打印到日志记录的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆