docker运行pseudoTTY(-t)即时标准输出,缓冲发生没有它

我有一个python包,我正在一个容器内运行。 Dockerfile说:

FROM frolvlad/alpine-python3 RUN apk --no-cache add ca-certificates COPY ./ /app/ RUN cd app && python3 setup.py install 

现在,一旦图像被build立,当我运行它使用这个命令…

 docker run --env-file ./envfile myimg sh -c 'myscript "$username" "$password"' 

…需要一分钟才能看到任何types的标准输出。 我也必须停止从另一个terminal的容器(Ctrl + C什么都不做)。

但是当我运行图像使用

 docker run -t --env-file ./envfile myimg sh -c 'myscript "$username" "$password"' 

(即join-t ),它的行为如预期(每5秒左右一些标准输出)。

这种行为的原因是什么? 我不知道究竟是什么原因造成的,因为我无法find相关的文件。

这是标准的Linux stdio行为。

如果要输出到文件或文件句柄(如stdout),则会以4k块的forms进行缓冲。 这是为了优化I / O处理。

如果目标是一个tty(terminal),缓冲区是基于行的。

参考: https : //www.turnkeylinux.org/blog/unix-buffering

在幕后,罪魁祸首是Unix stdio缓冲,在Linux上由glibc实现,glibc是一个系统库,大多数程序在C中用来处理基本的东西(例如IO)。

Unix缓冲背后的想法是通过在应用程序级别(AKA userland)将IO调用进行批处理来提高IO性能,从而最小化相对昂贵的内核级读/写操作。

默认情况下,写入标准输出通过一个4096字节的缓冲区,除非标准输出恰好是terminal/ tty,在这种情况下,它是行缓冲。