docker exec 搞乱了终端换行符?

docker exec 搞乱了终端换行符?

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

例如:

$ docker exec -it foo sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
   "a": "b",
              "c": "d"
                      }
                       $

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

$ sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq
{
  "a": "b",
  "c": "d"
}

...正如预期的那样。

如果我通过 管道传输输出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  

如果我尝试通过发出自己来排除 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                                  }..
$

...这意味着它是docker exec

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

我的终端(暂时)出了什么问题docker exec,我该如何修复它?

答案1

很有意思...

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

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


查看手册页docker exec

  -t, --tty=true|false
      Allocate a pseudo-TTY. The default is false.

伪 TTY(PTY)允许系统与您(人类)进行交互...结果是 docker 在整个exec容器内分配一个新的 PTY,以及如何生成换行符、终端高度和宽度等内容开始发挥作用 - 以及大量其他内容。

我无法完全解释这一点,但这并不是你想要从管道中得到的东西。


另请比较:

$ docker exec -i sharp_einstein sh -c 'stty'
stty: 'standard input': Inappropriate ioctl for device
$ docker exec -i -t sharp_einstein sh -c 'stty'
speed 38400 baud; line = 0;
-brkint -imaxbel
$ stty
speed 38400 baud; line = 0;
-brkint -imaxbel

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

  * [-]ocrnl
          translate carriage return to newline

  * [-]onlcr
          translate newline to carriage return-newline

有类似的观察结果sst -t,例如:使用 pty(通过 ssh)并通过管道传输到更多

答案2

您是否尝试在“echo”上使用“-n”-n“ 喜欢 :

$ docker exec -it upbeat_mendeleev sh -c 'echo {\"a\":\"b\",\"c\":\"d\"}' | jq .
{
   "a": "b",
              "c": "d"
                      }


$ docker exec -it upbeat_mendeleev sh -c 'echo -n {\"a\":\"b\",\"c\":\"d\"}' | jq .
{
  "a": "b",
  "c": "d"
}

相关内容