运行子流程并将输出打印到日志记录 [英] Run subprocess and print output to logging
问题描述
我正在寻找从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
的文档,特别是关于stdout
和stderr
:
stdin
,stdout
和stderr
指定执行的程序的标准 输入,标准输出和标准错误文件句柄. 有效值为PIPE
,即现有文件描述符(正数 整数),一个现有文件对象和None
.PIPE
表示 应该创建到孩子的新管道.使用默认设置None
,将不会发生重定向;孩子的文件句柄将是 从父级继承.另外,stderr
可以是STDOUT
, 表示子进程的stderr
数据应 被捕获到与stdout
相同的文件句柄中.
stdin
,stdout
andstderr
specify the executed program’s standard input, standard output and standard error file handles, respectively. Valid values arePIPE
, an existing file descriptor (a positive integer), an existing file object, andNone
.PIPE
indicates that a new pipe to the child should be created. With the default settings ofNone
, no redirection will occur; the child’s file handles will be inherited from the parent. Additionally,stderr
can beSTDOUT
, which indicates that thestderr
data from the child process should be captured into the same file handle as forstdout
.
因此您可以看到可以使用文件对象,也可以使用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屋!