Допустим, у меня есть это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. Хотя большинство приложений очистят свои ресурсы и остановятся, некоторые могут этого не сделать.
решение1
trap
реагирует на сигналы вызывающего процесса. Но вы должны вызвать его до получения сигнала. Я имею в виду, в начале вашего скрипта.
Кроме того, если вы хотите использовать kill -- -$$
, который также посылает сигнал вашему скрипту, вам необходимо очистить ловушку перед выполнением kill, иначе вы закончите с бесконечнымубить && ловушкапетля.
Например:
#!/bin/bash
exit_script() {
echo "Printing something special!"
echo "Maybe executing other commands!"
trap - SIGINT SIGTERM # clear the trap
kill -- -$$ # Sends SIGTERM to child/sub processes
}
trap exit_script SIGINT SIGTERM
echo "Some other text"
#other commands here
sleep infinity
Как объясняется в комментариях, проблема в том, что скрипт получает сигнал, но ждет завершения программы сна, прежде чем обрабатывать полученный сигнал. Поэтому вам следует завершить дочерние процессы (в данном случае процесс сна), чтобы запустить действие ловушки. Это можно сделать примерно так:
kill -- -$(pgrep script.sh)
Или как указано в комментариях:
killall -g script.sh