docker-compose down 不会通过两层 bash 脚本向下级联 SIGTERM
docker-compose down does not cascade down SIGTERM through two layers of bash scripts
我有两个 bash 脚本,一个作为我的 docker 容器的入口点,如下所示:
#!/bin/bash
sig_handler()
{
echo "[LAYER1] killing children with pid "$pid
[[ $pid ]] && kill $pid
exit 1
}
trap 'sig_handler' SIGINT SIGTERM
while true; do
./nextlayer.sh & pid=$!
wait $pid
echo "Waiting 5 seconds before starting a new worker..."
sleep 5
done
现在 nextlayer.sh 也有某种信号陷阱,但也会尝试清理一些东西,如下所示:
#!/bin/bash
sig_handler()
{
echo "[LAYER2] Exiting main script and cleaning up tasks"
cleanup
}
cleanup()
{
echo "[LAYER2] Cleaning up"
sleep 5
echo "Cleanup done, exiting with SIGTERM"
exit 143
}
trap 'sig_handler' SIGINT SIGTERM
i=0
while [ $i -lt 10 ]
do
i=$(( $i + 1 ))
sleep 1
echo $i
done
这只是在 i < 10 时循环遍历 i 并每秒回显结果。当 运行 本地入口点脚本没有 docker 并按 ctrl + c 退出时,脚本按预期终止并输出清理功能内容。
然而,当将相同的逻辑应用于 docker 容器时,SIGTERM 仅到达入口点脚本中的 sighandler,而不会到达第二层脚本中。有人知道我做错了什么吗?
我找到了解决方案。
在入口点脚本的sig_handler函数中,下面的wait指令解决了:
sig_handler()
{
echo "[LAYER1] killing children with pid "$pid
[[ $pid ]] && kill $pid
wait $pid # this is crucial
exit 1
}
所以在实际退出容器之前,wait $pid 强制它实际等待后续脚本的退出。我测试了这 5 次脚本迭代,一切正常。
我有两个 bash 脚本,一个作为我的 docker 容器的入口点,如下所示:
#!/bin/bash
sig_handler()
{
echo "[LAYER1] killing children with pid "$pid
[[ $pid ]] && kill $pid
exit 1
}
trap 'sig_handler' SIGINT SIGTERM
while true; do
./nextlayer.sh & pid=$!
wait $pid
echo "Waiting 5 seconds before starting a new worker..."
sleep 5
done
现在 nextlayer.sh 也有某种信号陷阱,但也会尝试清理一些东西,如下所示:
#!/bin/bash
sig_handler()
{
echo "[LAYER2] Exiting main script and cleaning up tasks"
cleanup
}
cleanup()
{
echo "[LAYER2] Cleaning up"
sleep 5
echo "Cleanup done, exiting with SIGTERM"
exit 143
}
trap 'sig_handler' SIGINT SIGTERM
i=0
while [ $i -lt 10 ]
do
i=$(( $i + 1 ))
sleep 1
echo $i
done
这只是在 i < 10 时循环遍历 i 并每秒回显结果。当 运行 本地入口点脚本没有 docker 并按 ctrl + c 退出时,脚本按预期终止并输出清理功能内容。
然而,当将相同的逻辑应用于 docker 容器时,SIGTERM 仅到达入口点脚本中的 sighandler,而不会到达第二层脚本中。有人知道我做错了什么吗?
我找到了解决方案。
在入口点脚本的sig_handler函数中,下面的wait指令解决了:
sig_handler()
{
echo "[LAYER1] killing children with pid "$pid
[[ $pid ]] && kill $pid
wait $pid # this is crucial
exit 1
}
所以在实际退出容器之前,wait $pid 强制它实际等待后续脚本的退出。我测试了这 5 次脚本迭代,一切正常。