为什么`docker run -t`可以使python刷新输出缓冲区?

时间:2019-07-08 07:25:47

标签: python docker

1。

Dockerfile:

FROM python:3
CMD ["python", "-m", "http.server"]

下一步执行时,您会看到看不到日志。

shubuntu1@shubuntu1:~/77$ docker build -t a:1 . --no-cache
...
Successfully tagged a:1
shubuntu1@shubuntu1:~/77$ docker run -d --name test a:1
9638189c0528fc98524b0b2f7bec72269186a3445795f0fcf974751a0d908f44
shubuntu1@shubuntu1:~/77$ docker logs test
shubuntu1@shubuntu1:~/77$

2。

一段时间以来,我在上面与之抗争,最后发现是由于程序缓冲区问题,所以我可以通过next进行修复:

Dockerfile:

FROM python:3
CMD ["python", "-u", "-m", "http.server"]

现在可以与-u一起使用:

shubuntu1@shubuntu1:~/77$ docker build -t a:1 . --no-cache
...
Successfully tagged a:1
shubuntu1@shubuntu1:~/77$ docker rm -f test
test
shubuntu1@shubuntu1:~/77$ docker run -d --name test a:1
68bc759a54ec3218b39e51404495a28d010a798b1d1e160ec7f68be3b18da9c7
shubuntu1@shubuntu1:~/77$ docker logs test
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

3。

但是当我在情况1下回退Dockerfile时:

Dockerfile:

FROM python:3
CMD ["python", "-m", "http.server"]

我在-t中用docker run找到了,缓冲区也如下刷新:

shubuntu1@shubuntu1:~/77$ docker build -t a:1 . --no-cache
...
Successfully tagged a:1
shubuntu1@shubuntu1:~/77$ docker rm -f test
test
shubuntu1@shubuntu1:~/77$ docker run -dt --name test a:1
f7cd1b5b3c272ff42c7aecd251e324b70030c046489048370689ba25b33191cc
shubuntu1@shubuntu1:~/77$ docker logs test
Serving HTTP on 0.0.0.0 port 8000 (http://0.0.0.0:8000/) ...

所以,我的问题是:为什么-t有这种作用?

1 个答案:

答案 0 :(得分:2)

使用-t/--tty运行docker容器似乎将伪终端附加到容器中的进程。

如果将stdout描述符附加到终端,则会对其进行行缓冲。
假定用户正在监视终端以查看进程的输出;经常打印数据被认为很重要。遇到换行符(\n)字符,缓冲区填满或过程结束时,缓冲区将立即刷新。

如果stdout连接到与终端不同的东西,则流被完全(或块)缓冲。在libc / glibc上,默认缓冲区大小为4096字节。缓冲区必须在刷新其内容之前填满。
当假定稍后将检查写入stdout的数据(例如日志文件)时,这将减少昂贵的写入系统调用的次数。

另请参阅Evan Klitzke的Stdout Buffering,PádraigBrady的Buffering in standard streamsstdout man page