当前位置: 首页 > 面试题库 >

运行子流程并将输出打印到日志

许学真
2023-03-14
问题内容

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

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

而且我敢肯定,有一种方法可以做到,而无需创建临时文件来存储进程输出。有任何想法吗?


问题答案:

我敢肯定有一种方法可以做到,而无需创建临时文件来存储进程输出

您只需要检查的文档Popen,尤其是有关stdout和的文档stderr

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

因此,您可以看到可以使用文件对象或PIPE值。这使您可以使用该communicate()方法来检索输出:

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

我会将您的代码重写为:

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


 类似资料:
  • 问题内容: 为了从我的Python脚本启动程序,我使用以下方法: 因此,当我启动像这样的过程时我的程序将等待直到该过程完成为止,然后我才能获得程序的完整输出。如果我正在运行需要一段时间才能完成的过程,这将很烦人。 我可以让我的程序通过在循环完成之前轮询过程输出来逐行写过程输出吗? 问题答案: 你可以在命令输出行之后立即使用处理行。这是显示典型用例的完整示例:

  • 问题内容: 我是一个相对较新的程序员,所以这可能是一个非常简单的问题,但是让我有些困惑。 我正在尝试将Java GUI的最终输出打印到打印机。现在,在我的GUI中,有了它,当您单击打印时,会弹出一个弹出窗口,列出可用的打印机,并根据您选择的打印机,将其打印到该打印机。 但是事实并非如此。我通过搜索互联网来解决此问题,从而获得了大部分代码,并找到了一些很有前途的代码。但是,它是从文件打印出来的。因此

  • 问题内容: 如何将Java输出同时输出到Shell控制台和某个文件中?那可能吗? 问题答案: 您可以在程序的开头包含以下几行:

  • 使用命令: /usr/bin/journalctl-o short-f |ncat{some ip}{some port} 将日志输出转发到某个远程日志跟踪应用程序。 问题是,我在打印输出中缺少systemd单元/服务名称,因此很难判断哪个服务生成哪个日志行。 例如,这是一条nginx生产线: 6月25日07:51:09本地主机bash[497]:10.23.132.98---[25/Jun/20

  • 问题内容: 在我的父脚本中,我执行以下操作: 在脚本中,我希望大多数日志消息都进入日志文件,但是我希望根据打印条件在控制台上打印一些消息: 但是它正在打印到outfile,我也想在控制台上打印 但这aslso不起作用。任何帮助,将不胜感激! 问题答案: 如果将stdout,stderr重定向,则可以尝试直接打印到控制台: 例:

  • 问题内容: 有没有一种方法可以将所有打印输出保存到python中的txt文件中?可以说我的代码中有这两行,我想将打印输出保存到名为的文件中。 我希望文件包含 问题答案: 给一个关键字参数,其中参数的值是文件流。我们可以使用以下功能创建文件流: 从Python文档中有关: 所述参数必须是与对象方法; 如果不存在或,将使用。 和文档: 打开并返回相应的文件对象。如果无法打开文件,则引发。 在作为第二个