我正在寻找从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
:
stdin
,stdout
并分别stderr
指定执行程序的标准输入,标准输出和标准错误文件句柄。有效值为PIPE
:现有文件描述符(正整数),现有文件对象和None
。PIPE
指示应创建到子级的新管道。使用默认设置时
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重定向,则可以尝试直接打印到控制台: 例:
我目前正在使用Jupyter笔记本,我想强制它将Python日志打印到输出单元格。 我用的是以前用这种方式工作的旧笔记本,可能是旧版本的Jupyter笔记本。 我将日志设置为: 但当我打电话时: 它不会在输出单元格中打印任何内容。它只是在我启动Jupyter笔记本的控制台中打印出内容。 我正在使用并且在我的虚拟环境中安装的包是: 单元格中的日志打印输出是否已更改?是否有某种方法可以强制将日志记录写