为什么`docker run -t`可以使python刷新输出缓冲区? [英] Why `docker run -t` could make python flush the output buffer?

查看:71
本文介绍了为什么`docker run -t`可以使python刷新输出缓冲区?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

1.

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.

我有一段时间在上面与之抗争终于发现是由于程序缓冲区问题,所以我可以用next修复:

I struggle against above for sometime & finally find it's because of the program buffer issue, so I can fix with 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 时:

But when I rollback the Dockerfile with situation 1:

Dockerfile:

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

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

I find with -t in docker run, the buffer also flush as next:

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 具有这种作用?

So, my question is: why -t have this effect?

推荐答案

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

Running a docker container with -t/--tty appears to attach a pseudo-terminal to the process in the container.

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

If an stdout descriptor is attached to a terminal, it is line buffered.
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.

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

If stdout is attached to something different than a terminal, the stream is fully (or block) buffered. On libc/glibc, the default buffer size is 4096 bytes. 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 (e.g. log files).

另请参见Evan Klitzke的标准缓冲

See also Stdout Buffering by Evan Klitzke, Buffering in standard streams by Pádraig Brady and the stdout man page.

这篇关于为什么`docker run -t`可以使python刷新输出缓冲区?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆