简体   繁体   English

Python 脚本打印输出仅出现在执行结束时,在外部调用它并将 stdout/stderr 记录到文件中时

[英]Python script printouts just appearing at the end of execution when calling it externally and logging stdout/stderr into file

I'm calling a script from another one by using:我正在使用以下方法从另一个脚本调用脚本:

command = 'python foo.py'
with open('./logs.txt', 'w') as file:
    p = Popen(command, shell=True, stderr=file, stdout=file)
    p.wait()

Where foo.py does several call for another script bar.py .其中foo.py多次调用另一个脚本bar.py

By doing this, unfortunately I get a behavior that I didn't want when it's writing to the text file.通过这样做,不幸的是,我在写入文本文件时得到了我不想要的行为。 The printouts are getting messed up and, for some reason, bar.py printouts appears before foo.py , which gets messy as the code follows a linear execution and the printouts I wanted to see were executed before calling bar.py .打印输出变得混乱,并且由于某种原因, bar.py打印输出出现foo.py之前,由于代码遵循线性执行并且我想看到的打印输出在调用bar.py之前执行,因此变得混乱。

When I use sys.stdout and sys.stderr and Popen's stdout and stderr , respectively, I don't see this behavior happening.当我分别使用sys.stdoutsys.stderr以及 Popen 的stdoutstderr时,我没有看到这种行为发生。

Any clue why this happens?任何线索为什么会发生这种情况?

Just to illustrate the situation, a crafted printout, when writing to external file (I will use a third script call for better exemplification):只是为了说明情况,一个精心制作的打印输出,写入外部文件时(我将使用第三个脚本调用以获得更好的示例):

[bar.py] This is print 1
[xyz.py] This is print 1
[foo.py] This is print 1
[foo.py] This is print 2
[foo.py] This is print 3

What I actually would like to see/it's happening when using sys' stdout / stderr :我真正想看到/使用 sys' stdout / stderr时发生的事情:

[foo.py] This is print 1
[bar.py] This is print 1
[foo.py] This is print 2
[xyz.py] This is print 1
[foo.py] This is print 3

For the foo.py printouts I'm just using Python's print() method.对于foo.py打印输出,我只是使用 Python 的print()方法。 Don't know about the external ones because it wasn't written by me.不知道外部的,因为它不是我写的。

Strangely this behavior happens on docker logs too, ie when I execute this chain on a container and want to see the printouts.奇怪的是,这种行为也发生在docker logs上,即当我在容器上执行此链并希望查看打印输出时。 So, I think it can be related in some way.所以,我认为它可以以某种方式相关。

How can I solve this?我该如何解决这个问题?

I expect this is due to output buffering .我预计这是由于output 缓冲造成的。

This answer on stack exchange suggests: 这个关于堆栈交换的答案表明:

... When process STDOUT is redirected to something other than a terminal, then the output is buffered into some OS-specific-sized buffer (perhaps 4k or 8k in many cases). ...当进程 STDOUT 被重定向到终端以外的东西时,output 被缓冲到一些特定于操作系统大小的缓冲区(在许多情况下可能是 4k 或 8k)。 Conversely, when outputting to a terminal, STDOUT will be line-buffered or not buffered at all, so you'll see output after each \n or for each character相反,当输出到终端时,STDOUT 将被行缓冲或根本不缓冲,因此您会在每个 \n 或每个字符之后看到 output

This answer may be helpful, it describes how to disable output buffering. 这个答案可能会有所帮助,它描述了如何禁用 output 缓冲。

The easy thing to try would be to tell Python to run unbuffered with the -u flag:尝试的简单方法是使用-u标志告诉 Python 运行无缓冲:

command = 'python -u foo.py'

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM