我正在使用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
命令中收集的输出将具有不可见 /不可打印的\r
字符会导致各种问题。
答案 0 :(得分:4)
tldr;这是tty
的默认行为,与docker无关。根据{{3}}。
在该票证中引用相关评论:
默认情况下,看起来确实是TTY会将换行符转换为CRLF
$ docker run -t --rm debian sh -c "echo -n '\n'" | od -c
0000000 \r \n
0000002
使用stty -onlcr禁用“将换行转换为回车换行符”会正确给出;
$ 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
确实在那里。
当我们查看ticket filed on github about your exact issue时,我们可以看到:
[-] onlcr:将换行符转换为回车换行符
故事的寓意,除非需要TTY,否则不要使用-t。
TTY行的结尾是CRLF,这不是Docker要做的。