Как Филипп упоминает в комментарии выше, Справочное руководство Bash § 3.7.6 "Сигналы" состояния в части:
Если Bash ожидает завершения команды и получает сигнал, для которого установлена ловушка, ловушка не будет выполнена до ее завершения.
Это на самом деле верно как для SIGINT, так и для SIGTERM; причина, по которой ваш подход работает для Ctrl- C, заключается в том, что Ctrl- C отправляет SIGINT на каждый процесс в группе процессов переднего плана, включая процесс sleep
, поэтому sleep
завершается немедленно и затем его родительский скрипт завершается.
Наиболее явный способ исправить это предлагает остальная часть абзаца, который я только что процитировал:
Когда Bash ожидает асинхронная команда через встроенную функцию wait
, прием сигнала, для которого установлена ловушка, заставит встроенную функцию wait
немедленно вернуться с состоянием выхода больше 128, сразу после чего ловушка будет выполнена.
Другими словами, вы можете заменить sleep 1h
на sleep 1h & wait
(где sleep 1h &
и wait
могут быть в отдельных строках или в одной строке, как вы предпочитаете), чтобы ваш trap вызывается немедленно (так что он может убить процесс sleep
).
В качестве альтернативы, вы можете исключить установку trap
и заменить sleep 1h
чем-то, что не будет работать так долго после выхода из скрипта ; например:
- al oop, который многократно спит ненадолго (например,
sleep 1s
), пока не пройдет час. read -t 3600
, который ожидает до 3600 секунд ( один час) для отображения текста на стандартном вводе. (Примечание: этот подход работает только в том случае, если на стандартном вводе фактически нет текста.)
(Они основаны на том факте, что l oop (в первом случае) или read
вызов (в последнем случае) является частью самого процесса Bash, а не раздвоенным дочерним процессом.)