Во-первых, что-то вроде
rm -f test/SIGTERM-TRAPPED && ./SIGTERM & sleep 0.2 && kill -TERM $! && sleep 0.5 && ls test
кажется гораздо более удобным способом проверки этого, чем перезагрузка при каждой попытке.
Теперь в строках нет ни bash, ни da sh запускать ловушку до тех пор, пока не закончится ожидание текущей команды (sleep infinity
).
Таким образом, целевой процесс SIGTERM
приводит к сбою wait
в sleep
с EINTR
(оболочка обработчик запускался, устанавливая флаг, что ловушка должна быть запущена позже) и оболочка wait
s снова. Поскольку дочерний процесс никогда не завершается, wait
никогда не завершается, а отложенный обработчик никогда не запускается.
Группа процессов, нацеленная на SIGTERM
(kill -TERM -$pid
в отличие от kill -TERM $pid
), убила бы sleep
child, и системный вызов wait в оболочке, таким образом, прекратит зацикливание, заставляя оболочку запускать ловушку.
rm -f test/SIGTERM-TRAPPED && ./SIGTERM & sleep 0.2 && kill -TERM -$! && sleep 0.5 && ls test
Я думаю, что правильное приложение должно убивать своих потомков, когда оно завершается.
Оболочки этого не делают, и вместо этого они полагаются на убийства в рамках всей группы процессов (Ctrl+C/Ctrl-\
предназначаются для всей группы процессов переднего плана) или SIGHUP
s в конце сеанса, чтобы заботиться о своих сбежавших детях.