次のコマンドがあります。
sudo docker logs -f <id> | awk '/Listening on / {print $3; exit 0;}'
私が理解したように、awkはパターンに一致する最初の行を見つけて正しい列を印刷してから終了します。しかし、これが常に起こるわけではありません。ほとんどの場合、正しい列を印刷して停止しますが、時々正しく終了することがあります。
頑張った
$ sudo stdbuf -i0 -o0 -e0 docker logs ... # hangs
$ sudo docker logs ... | cat | awk ... # hangs
mkfifo
最小限の例を生成しようとしながら、 を使用してパイプを作成してみましたがcat foo | awk ...
停止しませんでした。
の出力はdocker logs -f <id>
次のとおりです。
Listening on 172.17.0.2/16
...
その後、開いたままになりますが、他の内容は書きません。
何が起こっているのか理解できません。もしアイデアをお持ちの方はいらっしゃいますか?
答え1
からman bash
:
シェルは、値を返す前にパイプライン内のすべてのコマンドが終了するのを待ちます。
Dockerはインストールされていませんが、次のことを試してください。
awk '/Listening on / {print $3; exit 0;}' <( sudo docker logs -f <id> )
または、次のことを試すことができます。
sudo docker logs -f <id> | (awk '/Listening on / {print $3; exit 0;}'; pkill -P $$ )
したがって、何が起こっているのかについての説明が役に立ちます。私は "docker log"コマンドが正常に終了しないと仮定します(-f ==次?)。
初期の問題は、awkがシャットダウンしたときにパイプがシャットダウンされなかったために発生しました。これは、パイプがまだdockerプログラムを待っていたためです(上記のbashのマニュアルページを参照)。
pkillは親IDが$$であるすべてを殺します。つまり、その瞬間にはただのドッカーだけです。
明らかに、「&」を使用してそのコマンドをバックグラウンドにして他のタスクを実行するのは良い考えではありません。そのコマンドも一緒に終了します!