Python 的 print 函数在 Docker 中没有输出
0. 问题
在 Docker 容器中运行 Python 写的 HTTPServer 时,发现 print 函数没有输出,但能正常输出 log 信息(例如1.1.1.1 - - [26/Feb/2025 14:31:53] "GET /some/path/ HTTP/1.0" 200 -)。
1. 解决方法
1.1 解决方法1-使用 print 的 flush 参数
仅需要将 print 函数的 flush 参数设置为 True 即可。
1 | |
1.2 解决方法2-添加环境变量 PYTHONUNBUFFERED
在 Dockerfile 中添加环境变量 PYTHONUNBUFFERED,并设置为 1。
1 | |
2. 原因
2.1 为什么 print 没有输出
在 Python 中,print 函数默认是输出到stdout,而 Python 在非交互环境(如 Docker 容器)中默认使用块缓冲模式,只有当缓冲区满或程序结束时才会输出。
Python docs 中对 sys.stdout 的说明如下:
When interactive, the
stdoutstream is line-buffered. Otherwise, it is block-buffered like regular text files. Thestderrstream is line-buffered in both cases. You can make both streams unbuffered by passing the-ucommand-line option or setting thePYTHONUNBUFFEREDenvironment variable.
可以使用以下代码来模拟这种情况:
1 | |
在 Docker 容器中运行该代码:
1 | |
在本问题中,print 没有输出的原因是缓冲区未满。
2.2 为什么 log 信息能输出
在 Python 中,logging 模块默认是输出到stderr,而 stderr 是行缓冲的,所以 log 信息能够正常输出。