web-dev-qa-db-ja.com

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(0aではなく0d0a)が導入されているように見えます)、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  

自分で\r\nを発行してDockerを除外しようとすると、問題ありません。

$ 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 infoServer Version: 18.03.1-ceを報告します。 docker -vDocker version 18.03.1-ce, build 9ee9f40を報告します。

docker execは(一時的に)端末に何をしましたか?また、どうすれば修正できますか?

4
Roger Lipscombe

とても興味深い...

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を介して)階段を上って、moreにパイプする場合

3
Attie

"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"
}
0
frbayart