简体   繁体   English

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

[英]Why `docker run -t` could make python flush the output buffer?

1. 1.

Dockerfile: Dockerfile:

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

When I execute next, you can see there is no log could be seen.当我接下来执行时,您可以看到没有日志可以看到。

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. 2.

I struggle against above for sometime & finally find it's because of the program buffer issue, so I can fix with next:我在上面挣扎了一段时间,最后发现这是因为程序缓冲区问题,所以我可以解决下一个问题:

Dockerfile: Dockerfile:

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

Works now with -u :现在与-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. 3.

But when I rollback the Dockerfile with situation 1:但是当我在情况 1 下回滚Dockerfile时:

Dockerfile: Dockerfile:

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

I find with -t in docker run , the buffer also flush as next:我发现在docker run使用-t ,缓冲区也如下刷新:

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/) ...

So, my question is: why -t have this effect?所以,我的问题是:为什么-t有这种效果?

Running a docker container with -t/--tty appears to attach a pseudo-terminal to the process in the container.使用-t/--tty运行 docker 容器似乎将伪终端附加到容器中的进程。

If an stdout descriptor is attached to a terminal, it is line buffered.如果 stdout 描述符附加到终端,则它是行缓冲的。
It is assumed that a user is monitoring the terminal for output of the process;假设用户正在监视终端以获取进程的输出; printing data frequently is considered important.经常打印数据被认为很重要。 The buffer is flushed as soon as a newline ( \\n ) character is encountered, the buffer fills up, or the process ends.一旦遇到换行符 ( \\n )、缓冲区填满或进程结束,缓冲区就会被刷新。

If stdout is attached to something different than a terminal, the stream is fully (or block) buffered.如果 stdout 附加到与终端不同的东西,则流被完全(或块)缓冲。 On libc/glibc, the default buffer size is 4096 bytes.在 libc/glibc 上,默认缓冲区大小为 4096 字节。 The buffer must fill up before the its contents are flushed.缓冲区必须在其内容被刷新之前填满。
This reduces the number of expensive write system calls when it is assumed that data written to stdout will be examined later (eg log files).当假设写入 stdout 的数据将在稍后检查(例如日志文件)时,这会减少昂贵的写入系统调用的数量。

See also Stdout Buffering by Evan Klitzke, Buffering in standard streams by Pádraig Brady and the stdout man page .又见标准输出缓冲埃文Klitzke,在标准流进行缓冲由哈灵顿布雷迪和标准输出手册页

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

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