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

时间:2019-03-07 00:18:58

标签: 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

但是,当我直接通过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字符会导致各种问题。

1 个答案:

答案 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:将换行符转换为回车换行符

再次引用ONLCR flag documentation

  

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