Execute Command on SIGINT or SIGTERM in Parent Script

bashprocessscriptingshell-scriptsignals

Let's say I have this 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

I want script.sh to execute the function exit_script whenever it receives SIGINT or SIGTERM
For example:

killall script.sh # it will send SIGTERM to my script

and I want my script to execute this

exit_script() {
    echo "Printing something special!"
    echo "Maybe executing other commands!"
    kill -- -$$ # Sends SIGTERM to child/sub processes
}

I tried to implement this feature using trap

trap exit_script SIGINT SIGTERM

The person who answered my question proved me wrong.
but it didn't work because trap seems to react only to signals sent to child/sub processes. As a beginner I couldn't decipher trap's man page so I probably missed the solution.

I guess that's what "real" programs like Chromium do when you send them SIGTERM

From https://major.io/2010/03/18/sigterm-vs-sigkill/

The application can determine what it wants to do once a SIGTERM is
received. While most applications will clean up their resources and
stop, some may not.

Best Answer

trap reacts to the calling process signals itself. But you must call it before the signal is received. I mean, at the beginning of your script.

Furthermore, if you want to use kill -- -$$, which sends the signal also to your script, you need to clear the trap before running the kill or you will end with an infinite kill && trap loop.

For example:

#!/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

As explained in the comments, the problem is that the script receives the signal but is waiting for the sleep program to end before processing the received signal. So, you should kill the child processes (the sleep process in this case) in order run the trap action. You can do that with something like the following:

kill -- -$(pgrep script.sh)

Or as stated in the comments:

killall -g script.sh