14

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.

4
  • 2
    generally swears are considered inapproriate for respectful discourse
    – cat
    Oct 1, 2016 at 14:20
  • edit suggestion approved ok, ok done, no fun I get it
    – bosadjo
    Oct 1, 2016 at 14:21
  • it's not that no fun is allowed, it's just that's considered offensive
    – cat
    Oct 1, 2016 at 15:57
  • 1
    @cat I've thought about your argument and you are right, sorry for my tomfoolery
    – bosadjo
    Oct 1, 2016 at 19:00

1 Answer 1

18

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
6
  • 1
    I'm probably missing something because it doesn't work, here is what I do. script.sh &; killall script.sh but it does nothing.
    – bosadjo
    Oct 1, 2016 at 14:24
  • I execute the script.sh &; # then I do my business; killall script.sh and it doesn't kill script.sh
    – bosadjo
    Oct 1, 2016 at 14:34
  • 1
    The problem probably is that the script receives the signal but is waiting for the sleep program to end before processing it. Try with ./script.sh & sleep 1 && kill -- -$(pgrep script.sh) to send a kill signal also to the child processes of your script.
    – zuazo
    Oct 1, 2016 at 14:36
  • @zuazo You should add this interesting and important information to your answer :)
    – cat
    Oct 1, 2016 at 15:59
  • 1
    Nice, bosa djo. I added your alternative solution to the answer ;-)
    – zuazo
    Oct 1, 2016 at 19:03

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .