我有以下命令:
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
在尝试生成一个最小的示例时,我还尝试使用, 和 using制作管道,cat foo | awk ...
但这并没有挂起。
的输出docker logs -f <id>
是
Listening on 172.17.0.2/16
...
然后它保持打开状态,但不写入任何其他内容。
我不明白发生了什么事——有人有什么想法吗?
答案1
从man bash
:
shell 在返回值之前等待管道中的所有命令终止。
我没有安装 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 $$ 的东西 - 也就是说,在那一刻,这只是 docker。
显然,用“&”将该命令放入后台然后运行其他东西并不是一个好主意 - 它们也会被杀死!