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 次脚本迭代,一切正常。