docker exec 搞乱了终端换行?

Rog*_*mbe 7 terminal newlines docker

当我将输出通过管道传输docker exec到另一个命令时,它似乎弄乱了我的终端的行结尾。

例如:

$ docker exec -it foo sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
   "a": "b",
              "c": "d"
                      }
                       $
Run Code Online (Sandbox Code Playgroud)

但是,如果我立即在主机上的同一终端中运行相同的命令:

$ sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
  "a": "b",
  "c": "d"
}
Run Code Online (Sandbox Code Playgroud)

...正如预期的那样。

如果我通过管道输出xxd,它似乎会引入一个 CR 字符以及 LF (0d0a,而不是 0a);它还弄乱了以下的输出xxd

$ docker exec -i -t foo sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | xxd
00000000: 7b22 6122 3a22 6222 2c22 6322 3a22 6422  {"a":"b","c":"d"
                                                                   00000010: 7d0d 0a  
Run Code Online (Sandbox Code Playgroud)

如果我尝试通过发出自己的声音来排除 docker \r\n,那就没问题:

$ printf "{\"a\":\"b\",\"c\":\"d\"}\r\n" | xxd
00000000: 7b22 6122 3a22 6222 2c22 6322 3a22 6422  {"a":"b","c":"d"
00000010: 7d0d 0a                                  }..
$
Run Code Online (Sandbox Code Playgroud)

...这意味着它是docker exec.

我的主机和容器都运行 Linux。docker info报道Server Version: 18.03.1-cedocker -v报道Docker version 18.03.1-ce, build 9ee9f40

我的终端(暂时)受到了什么docker exec影响?我该如何修复它?

Att*_*tie 5

很有意思...

docker run -d ubuntu:latest sleep infinity
Run Code Online (Sandbox Code Playgroud)
$ docker exec -i sharp_einstein sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
  "a": "b",
  "c": "d"
}
Run Code Online (Sandbox Code Playgroud)
$ docker exec -it sharp_einstein sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
  "a": "b",
  "c": "d"
}
Run Code Online (Sandbox Code Playgroud)
$ docker exec -i -t sharp_einstein sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
   "a": "b",
              "c": "d"
                      }
Run Code Online (Sandbox Code Playgroud)

分离-i-t允许问题出现......(可能是一个错误?)


查看手册页docker exec

  -t, --tty=true|false
      Allocate a pseudo-TTY. The default is false.
Run Code Online (Sandbox Code Playgroud)

伪 TTY(PTY)允许系统与你(人类)交互...结果是 docker 在(容器内)的持续时间内分配一个新的 PTY exec,以及如何生成换行符、终端的高度和宽度以及许多其他因素都会发挥作用。

我无法完全解释它,但这不是您想要从正在输入管道的东西中得到的。


还比较:

  -t, --tty=true|false
      Allocate a pseudo-TTY. The default is false.
Run Code Online (Sandbox Code Playgroud)
$ docker exec -i sharp_einstein sh -c 'stty'
stty: 'standard input': Inappropriate ioctl for device
Run Code Online (Sandbox Code Playgroud)
$ docker exec -i -t sharp_einstein sh -c 'stty'
speed 38400 baud; line = 0;
-brkint -imaxbel
Run Code Online (Sandbox Code Playgroud)

stty能够控制 PTY 对回车符和换行符的处理,尽管这些选项对我来说没有任何影响。从手册页:

  * [-]ocrnl
          translate carriage return to newline

  * [-]onlcr
          translate newline to carriage return-newline
Run Code Online (Sandbox Code Playgroud)

也有类似的观察结果sst -t,例如:使用 pty(通过 ssh)时的阶梯式操作以及通过管道连接到更多