Если я переключаюсь с SIGINT на любой другой сигнал (я пробовал SIGTERM, SIGUSR1) ловушка печатает "Ouch", как и ожидалось.
По-видимому, вы не пробовали SIGQUIT; Вы, вероятно, обнаружите, что он ведет себя так же, как SIGINT.
Проблема заключается в контроле заданий.
В первые дни Unix, всякий раз, когда оболочка помещает процесс или конвейер в фон, он настроил эти процессы на игнорирование SIGINT и SIGQUIT, таким образом, они не будут прекращены, если пользователь впоследствии набрано Ctrl+C (прерывание) или Ctrl+ (выход) для задачи переднего плана. Когда появился контроль за заданиями, он принес с собой группы процессов, и так теперь все, что нужно сделать оболочке помещает фоновое задание в новую группу процессов; до тех пор, пока это не является текущей группой терминальных процессов, Процессы не будут видеть сигналы, поступающие с клавиатуры (Ctrl+C, Ctrl+ и Ctrl+Z (SIGTSTP)). Оболочка может оставлять фоновые процессы с расположением сигнала по умолчанию. На самом деле, это, вероятно, должно быть, чтобы процессы были убиваются. по Ctrl+C, когда они вынесены на передний план.
Но неинтерактивные оболочки не используют управление заданиями. Имеет смысл, что неинтерактивная оболочка будет отступать назад к старому поведению игнорирования SIGINT и SIGQUIT для фоновых процессов, по исторической причине — чтобы разрешить выполнение фоновых процессов, даже если им посылаются сигналы клавиатурного типа. А сценарии оболочки выполняются в неинтерактивных оболочках.
И, если вы посмотрите на последний абзац под командой
trap
в bash(1) вы увидитеСигналы, игнорируемые при входе в оболочку, не могут быть захвачены или сброшены.
Итак, если вы запустите
./scriptb.sh &
из командной строки оболочки interactive, его сигнальные диспозиции остаются в покое (даже если это отодвинуто на задний план), и командаtrap
работает должным образом. Но, если вы запустите./scripta.sh
(с&
, или без него), он запускает сценарий в неинтерактивной оболочке. И когда эта неинтерактивная оболочка запускается./scriptb.sh &
, он настраивает процессscriptb
на игнорирование прерывания и завершение работы. И поэтому командаtrap
вscriptb.sh
молча терпит неудачу.