Допустим, у меня есть это script.sh
#!/bin/bash
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
kill -- -$$ # Sends SIGTERM to child/sub processes
}
echo "Some other text"
#other commands here
sleep infinity
Я хочу script.sh
выполнить функцию exit_script
всякий раз, когда она получает SIGINT
или, SIGTERM
например:
killall script.sh # it will send SIGTERM to my script
и я хочу, чтобы мой сценарий выполнил это
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
kill -- -$$ # Sends SIGTERM to child/sub processes
}
Я пытался реализовать эту функцию с помощью trap
trap exit_script SIGINT SIGTERM
Человек, который ответил на мой вопрос, доказал, что я неправ.
но это не сработало, потому что, trap
кажется, реагирует только на сигналы, посылаемые дочерним процессам. Будучи новичком, я не мог расшифровать trap
справочную страницу, поэтому, вероятно, пропустил решение.
Я полагаю, именно это и делают "настоящие" программы, такие как Chromium, когда вы их отправляете SIGTERM
С https://major.io/2010/03/18/sigterm-vs-sigkill/
Приложение может определить, что оно хочет сделать после получения SIGTERM. Хотя большинство приложений будут очищать свои ресурсы и останавливаться, некоторые могут этого не делать.
Ответы:
trap
сам реагирует на сигналы вызывающего процесса. Но вы должны позвонить до получения сигнала. Я имею в виду, в начале вашего сценария.Кроме того, если вы хотите использовать функцию
kill -- -$$
, которая посылает сигнал также в ваш сценарий, вам нужно очистить ловушку перед выполнением kill, иначе вы закончите бесконечным циклом kill && trap .Например:
Как поясняется в комментариях, проблема заключается в том, что сценарий получает сигнал, но ожидает завершения спящей программы перед обработкой принятого сигнала. Таким образом, вы должны уничтожить дочерние процессы (в данном случае спящий процесс), чтобы запустить действие trap. Вы можете сделать это примерно так:
Или как указано в комментариях:
источник
./script.sh & sleep 1 && kill -- -$(pgrep script.sh)
отправить сигнал уничтожения также дочерним процессам вашего скрипта.