为什么“ docker run -t”输出在命令输出中包含\ r?

Ahm*_*gle 6 docker

我正在使用Docker客户端版本:18.09.2。

当我以交互方式启动容器并运行date命令,然后将其输出通过管道hexdump进行检查时,我看到的\n是预期的结尾:

$ docker run --rm -i -t alpine
/ # date | hexdump -c
0000000   T   h   u       M   a   r           7       0   0   :   1   5
0000010   :   0   6       U   T   C       2   0   1   9  \n
000001d
Run Code Online (Sandbox Code Playgroud)

但是,当我date直接将命令作为入口点传递并运行容器时,\r \n每次输出中都有新行时,都会得到提示。

$ docker run --rm -i -t --entrypoint=date alpine | hexdump -c
0000000   T   h   u       M   a   r           7       0   0   :   1   6
0000010   :   1   9       U   T   C       2   0   1   9  \r  \n
000001e
Run Code Online (Sandbox Code Playgroud)

真奇怪

当我省略-t(不分配任何TTY)时,它完全不会发生:

docker run --rm -i --entrypoint=date alpine | hexdump -c
0000000   T   h   u       M   a   r           7       0   0   :   1   7
0000010   :   3   0       U   T   C       2   0   1   9  \n
000001d
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?

这听起来很危险,因为我docker run在脚本中使用了命令,并且如果我忘记-t从脚本中省略了,我将从docker run命令中收集的输出将包含不可见的 /不可打印的\r字符,这可能会导致各种问题。

Gav*_*ler 7

tldr; 这是tty默认行为,与 docker 无关。根据在 github 上提交的关于您的确切问题票证


引用该票证中的相关评论:

看起来这确实是 TTY 默认情况下将换行符转换为 CRLF

$ docker run -t --rm debian sh -c "echo -n '\n'" | od -c
0000000   \r  \n
0000002
Run Code Online (Sandbox Code Playgroud)

使用 stty -onlcr 正确禁用“将换行符转换为回车换行符”;

$ docker run -t --rm debian sh -c "stty -onlcr && echo -n '\n'" | od -c
0000000   \n
0000001
Run Code Online (Sandbox Code Playgroud)

默认 TTY 选项似乎由内核设置...在我的 linux 主机上它包含:

/*
 * Defaults on "first" open.
 */
#define TTYDEF_IFLAG    (BRKINT | ISTRIP | ICRNL | IMAXBEL | IXON | IXANY)
#define TTYDEF_OFLAG    (OPOST | ONLCR | XTABS)
#define TTYDEF_LFLAG    (ECHO | ICANON | ISIG | IEXTEN | ECHOE|ECHOKE|ECHOCTL)
#define TTYDEF_CFLAG    (CREAD | CS7 | PARENB | HUPCL)
#define TTYDEF_SPEED    (B9600)
Run Code Online (Sandbox Code Playgroud)

ONLCR 确实在那里。

当我们查看ONLCR标志文档时,我们可以看到:

[-]onlcr:将换行符转换为回车换行符

再次引用github 票证

故事的寓意,除非您想要 TTY,否则不要使用 -t。
TTY 行结尾是 CRLF,这不是 Docker 的做法。