我正在使用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的工作。