出力を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 info
はServer Version: 18.03.1-ce
を報告します。 docker -v
はDocker version 18.03.1-ce, build 9ee9f40
を報告します。
docker exec
は(一時的に)端末に何をしましたか?また、どうすれば修正できますか?
とても興味深い...
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にパイプする場合
"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"
}