Выполнить команду или функцию, когда сигнал SIGINT или SIGTERM отправляется непосредственно родительскому скрипту, а не дочерним процессам.

Выполнить команду или функцию, когда сигнал SIGINT или SIGTERM отправляется непосредственно родительскому скрипту, а не дочерним процессам.

Допустим, у меня есть это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

Связанный контент