带有子进程的python日志记录:获取有序输出,因为它在日志文件中也显示在屏幕上

Man*_*gia 3 python logging subprocess stdout

我有一个python脚本(script1.py),它生成子进程,如下所示:

print 'This is the main script'
status=os.system(command)
Run Code Online (Sandbox Code Playgroud)

现在我执行脚本并重定向stdoutput,如下所示:

python script1.py > log.txt
Run Code Online (Sandbox Code Playgroud)

文件log.txt首先包含subprocess命令的输出(使用os.system调用),并且仅在字符串'This is the main script'之后.我期待相反的顺序!

如果我使用subprocess而不是os.system,情况仍然是相同的:

print 'This is the main script'
p=subprocess.Popen(command,shell=True, stdout=None, stderr=subprocess.STDOUT)
status=p.returncode
Run Code Online (Sandbox Code Playgroud)

那么如何将stdoutput重定向到文件并确保所有子进程以正确的顺序写入该文件?请注意,如果我不重定向标准输出,则日志消息的顺序是正确的(因为它显示在屏幕上)!

UPDATE

这解决了我的问题(如描述这里):

sys.stdout = os.fdopen(sys.stdout.fileno(), 'w', 0)
Run Code Online (Sandbox Code Playgroud)

或者,也可以强制刷新打印的内容:

sys.stdout.flush()
Run Code Online (Sandbox Code Playgroud)

但是,我认为这并不理想,因为它应该在每个打印命令之后完成.所以我使用了第一种方法,它的优点是我可以实时检查日志,而无需等待计算在写入缓冲输出文件之前结束.

Eli*_*Eli 5

使用日志记录模块.打印对此不可靠.例:

import logging
rootLogger = logging.getLogger()

proc = subprocess.Popen(["cat", "/etc/services"], stdout=subprocess.PIPE, shell=True)
(out, err) = proc.communicate()
logger.INFO('This is the main script. Here\'s the program output:')
logger.INFO(out)
Run Code Online (Sandbox Code Playgroud)

  • @Mannaggia你会遇到其他类似的问题.打印语句不适合生产使用.您可以继续寻找hacky解决方案来保留它们,但如果切换到日志记录,从长远来看,您会更加快乐.它还可以让您对记录在哪里的内容进行更细粒度的控制. (2认同)