Почему сценарий bash не дожидается завершения своих дочерних процессов, прежде чем выйти из родительского сценария при получении Sigterm?

trap exit_gracefully TERM

exit_gracefully() {
    echo "start.sh got SIGTERM"
    echo "Sending TERM to child_process_1_pid: ${child_process_1_pid}"
    echo "Sending TERM to child_process_2_pid: ${child_process_2_pid}"
    echo "Sending TERM to child_process_3_pid: ${child_process_3_pid}"
    kill -TERM ${child_process_1_pid} ${child_process_2_pid} ${child_process_3_pid}
}

consul watch -http-addr=${hostIP}:8500 -type=key -key=${consul_kv_key} /child_process_1.sh 2>&1 &
child_process_1_pid=$!

/child_process_2.sh &
child_process_2_pid=$!

/child_process_3.sh &
child_process_3_pid=$!

/healthcheck.sh &

/configure.sh

# sleep 36500d &
# wait $!

wait ${child_process_1_pid} ${child_process_2_pid} ${child_process_3_pid}

echo 'start.sh exiting'

start.sh - родительский скрипт. Когда SIGTERM перехватывается, он пересылается трем его дочерним процессам. Если # sleep 36500d & # wait $! закомментирован (удален из кода), start.sh не ждет, пока child_process_1.sh, child_process_2.sh и child_process_3.sh перейдут в получить SIGTERM, обработать его и выйти перед выходом из родительского процесса (start.sh), вместо этого start.sh завершится сразу после получения SIGTERM, даже до того, как дочерние процессы смогут его обработать. Но если я оставлю sleep 36500d & wait $! без комментариев в коде, родительский процесс (start.sh) будет ждать, пока дочерние процессы (1, 2 и 3) получат, обработают Sigterm и выйдут первым, прежде чем выходить из себя.

Почему эта разница существует, даже если я жду 3 pid (дочерних процессов) в любом случае? Зачем мне спать, когда я жду 3 пидоров?


person JavaDeveloper    schedule 30.07.2019    source источник
comment
Проверьте значение, возвращаемое функцией wait. Обычно, если он больше 128, значит, он был преждевременно прерван сигналом (сигналом $? - 128), поэтому вы, возможно, хотите сделать что-то вроде while wait $pid1 $pid2 $pid3; test $? -ge 128; do : ; done   -  person William Pursell    schedule 30.07.2019


Ответы (1)


Получение сигнала приведет к возврату любой выполняющейся команды wait.

Это связано с тем, что цель сигнала - прервать процесс в том, что он делает в данный момент.

Все эффекты, которые вы видите, являются просто результатом текущего возврата wait, запуска обработчика и продолжения сценария с того места, где wait завершился.

person that other guy    schedule 30.07.2019
comment
Итак, можем ли мы добавить wait в exit_gracefully (при условии, что тот же PID не будет переработан и повторно использован снова)? - person anishsane; 30.07.2019
comment
Я бы просто зациклился, пока wait не выйдет успешно, потенциально защищенный флагом, установленным обработчиком - person that other guy; 30.07.2019