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



我正在使用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

但是,当我直接将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

这很奇怪。

当我省略-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

这里发生了什么?

这听起来很危险,因为我在脚本中使用docker run命令,如果我忘记了从脚本中省略-t,我将从docker run命令收集的输出将具有 Invisible /nonrabibler字符可能引起各种问题。

tldr;这是tty默认行为,与Docker无关。根据Github上有关您的确切问题的票证。


引用该票中的相关评论:

看来这确实是TTY,默认情况下将新线转换为CRLF

$ docker run -t --rm debian sh -c "echo -n 'n'" | od -c
0000000   r  n
0000002

用stty -onlcr正确地禁用"将newline转换为运输返回新线"。

$ docker run -t --rm debian sh -c "stty -onlcr && echo -n 'n'" | od -c
0000000   n
0000001

默认的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)

ONLCR确实存在。

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

[ - ] ONLCR:将新线转换为马车返回newline

再次引用GitHub票:

故事的寓意,除非想要tty,否则不要使用-t。
TTY线的结尾是CRLF,这不是Docker的工作。

最新更新