Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 当使用subprocess.call()时,如果您使用disctionary配置进行日志记录,如何将其设置为将stdout重定向到日志文件的方式?_Python_Logging_Batch File_Stdout_Io Redirection - Fatal编程技术网

Python 当使用subprocess.call()时,如果您使用disctionary配置进行日志记录,如何将其设置为将stdout重定向到日志文件的方式?

Python 当使用subprocess.call()时,如果您使用disctionary配置进行日志记录,如何将其设置为将stdout重定向到日志文件的方式?,python,logging,batch-file,stdout,io-redirection,Python,Logging,Batch File,Stdout,Io Redirection,我正在尝试用Python重写此批处理行: mkdir %TEMP%\FW >> %LOGDETAILS% 2>&1 使用subprocess.call时,如果使用字典配置进行日志记录,如何将其设置为将stdout重定向到日志文件 到目前为止,我的Python代码是这样的,这只是其中的一部分: DICT_CONFIG = {#I have my settings in here} logging.config.dictConfig(DICT_CONFIG

我正在尝试用Python重写此批处理行:

mkdir %TEMP%\FW >> %LOGDETAILS% 2>&1
使用subprocess.call时,如果使用字典配置进行日志记录,如何将其设置为将stdout重定向到日志文件

到目前为止,我的Python代码是这样的,这只是其中的一部分:

    DICT_CONFIG = {#I have my settings in here}
    logging.config.dictConfig(DICT_CONFIG)
    logdetails = logging.getLogger('SikuliScriptDetails_Logger')

    def my_function():
        logdetails.info("---------Benginning Tests--------------")
        #Set Project Name, Disable Feedback Dialogs by setting launches to 41
        returncode = subprocess.call(["regedit", "-s", "MainFolder/FwSetup.reg"], stderr = STDOUT, stdout = logdetails)
我不能测试我的程序相当长一段时间,直到我有一些其他模块准备好。但我的重定向尝试是否正确?这是否能够将[regedit,-s,MainFolder/FwSetup.reg]的输出记录到我的logdetails文件记录器中

我是否有必要先执行stderr=STDOUT,就像我在将STDOUT发送到logdetails文件记录器之前所做的那样

还有,有人知道41是什么意思吗?我不知道该怎么办

PS:我已经看过了,但我还是不明白,因为他们没有使用字典配置来记录日志

更新:PS:我还研究了如何理解批处理代码行

更新2:对不起,我一开始给你的代码行错了。我应该在这里粘贴的批处理文件是:

"regedit", "-s", "VBoxScripts/FwSetup.reg"

不是这个:mkdir%TEMP%\FW>%LOGDETAILS%2>&1谢谢。

您的问题有点困惑

首先是日志位。使用哪种机制配置日志记录并不重要;最后,您仍然会得到一个使用相同方法的Logger对象。您所做的似乎是合理的,尽管使用“SikuliScriptDetails\u Logger”作为记录器的名称有点奇怪

接下来,这里是:

我是否有必要先执行stderr=STDOUT,就像我在将STDOUT发送到logdetails文件记录器之前所做的那样

设置stderr=STDOUT意味着,如下所述:

…子进程中的stderr数据应捕获到与stdout相同的文件句柄中

换句话说,如果您想同时记录stdout和stderr,那么是的,您确实需要这样做;如果您只想记录stdout或stderr,或者分别记录它们,那么不,您不应该这样做

从您的批处理行中,听起来您确实希望将stdout和stderr混合在一起,在这种情况下,您做的是正确的

最后,还有你认为是标准的东西。来自同一文件:

有效值包括PIPE、DEVNULL、现有文件描述符、正整数、现有文件对象和None

特别是,您不能给它一个Logger对象;您必须给它一个文件对象或管道

如果您只想将stdout和stderr附加到记录器正在使用的同一个文件中,您可以获取记录器的file对象并传递它。但是,一种更简单的方法是,首先不使用日志记录,只需打开一个文件,将头写入该文件,并将其作为stdout参数传递。例如:

with open(log_details_path, 'a') as logfile:
    logfile.write("---------Benginning Tests--------------\n")
    returncode = subprocess.call(["regedit", "-s", "MainFolder/FwSetup.reg"], stdout=logfile, stderr=STDOUT)
child_output = subprocess.check_output(["regedit", "-s", "MainFolder/FwSetup.reg"], stderr = STDOUT)
for line in child_output.splitlines():
    logdetails.info(line)
但是,考虑到您首先使用的是日志记录,听起来您真正想要的是这样的:读取stderr的每一行,并将其记录为单独的日志消息。如果是这样,您需要使用管道。如果您需要连续地将其流到日志中,那么这将花费很长的时间,发送大量数据,可能在中间失败……,您需要从管道中显式读取,然后记录所得到的数据。但如果没有,您可以使用communicate,甚至检查_输出。例如:

with open(log_details_path, 'a') as logfile:
    logfile.write("---------Benginning Tests--------------\n")
    returncode = subprocess.call(["regedit", "-s", "MainFolder/FwSetup.reg"], stdout=logfile, stderr=STDOUT)
child_output = subprocess.check_output(["regedit", "-s", "MainFolder/FwSetup.reg"], stderr = STDOUT)
for line in child_output.splitlines():
    logdetails.info(line)

将输出重定向到文件很容易,而通过日志模块进行重定向则更难。假设您真正想要的是python等效于将stdout和stderr管道化到一个文件,那么您可以执行以下操作:

log_details = "SikuliScriptDetails.log"
returncode = subprocess.call(
    ["regedit", "-s", "MainFolder/FwSetup.reg"],
    stdout=open(log_details, 'a'), 
    stderr=subprocess.STDOUT)
如果担心文件关闭,可以使用with子句:

log_details = "SikuliScriptDetails.log"
with open(log_details, 'a') as log_fp:
    returncode = subprocess.call(
        ["regedit", "-s", "MainFolder/FwSetup.reg"],
        stdout=log_fp, 
        stderr=subprocess.STDOUT)
如果要将stdout记录为info,将stderr记录为warn,可以使用线程:

import threading
import subprocess

def log_thread(pipe, logger):
    for line in pipe:
        logger(line.strip())

def my_call(logger, cmd, **kw):
    proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
        **kw)
    stdout = threading.Thread(target=log_thread, args=(proc.stdout, logger.info))
    stdout.start()
    stderr = threading.Thread(target=log_thread, args=(proc.stderr, logger.warn))
    stderr.start()
    stdout.join()
    stderr.join()
    return proc.wait()

这是一个非常令人困惑的问题!您说您想在python中使用“mkdir”,答案是使用os.mkdir或os.makedirs,但随后调用regedit。您想使用日志模块还是将输出重定向到一个文件?如果您只是想将输出重定向到一个文件,那么首先为什么要使用日志模块?我想记录/记录子进程生成的所有内容。@t我想使用日志模块。@Alain:嗯,日志模块不会执行与批处理示例相同的操作。使用日志将向每个日志消息添加标准日志头;您的批处理示例只是将未修改的输出和错误附加到文本文件中。所以,如果有一个问题说我正在试图重写这个批处理文件,然后显示您试图使用日志记录,那么肯定会让人感到困惑。你必须解释你到底想做什么,否则没人能告诉你怎么做。这很方便。我希望在我开始当前项目时看到这样的指导。谢谢分享。尽管如此,对于项目的这一步,我将在必要时制作大量subprocess.call或subprocess.Popen,并希望能够像下面的批处理代码那样处理每一个subprocess.call或subprocess.Popen
LOGDETAILS=V\SikuliScriptDetails.log文件:regedit-s VBoxScripts\FwSetup.reg>>%LOGDETAILS%2>&1@Alain,我将第一个示例更改为附加到日志文件。它现在执行与您的shell示例相同的操作。您的日志文件名与前面的斜杠不太正确,所以我只在本地目录中使用了一个。将其更改为所需内容。@Alain,如果要使用第二个示例,则需要单独设置日志处理程序。这只是演示了如何将输出输入记录器。我将很高兴在获得第一个样本后立即确认。在进行多个子流程调用时,看起来更易于管理。谢谢你。我将继续投票选出最有希望的答案。在第一个例子中,我是否需要关闭日志详细信息?我需要先关闭它,然后再从另一个子流程向其添加更多内容。调用?您的答案与我的意图最接近。谢谢你给我的清楚解释。这是你答案的最后一部分,似乎是我需要实现的。但是为什么我需要在末尾再次添加returncode=subprocess.call[regedit,-s,MainFolder/FwSetup.reg],stderr=STDOUT,STDOUT=logfile?太好了!如果另一个人不来,我一定会来的。谢谢