Search code examples
bashshellsignalssleep

bash: sleep process not getting killed


I wrote a simple bash script which does nothing but sleeps.

#!/bin/bash

echo "Sleeping..."
sleep 180s

I see two processes running on my system after I run the script:

user 22880  0.0  0.0  12428  1412 pts/28   S+   20:12   0:00 /bin/bash ./sleep.sh
user 22881  0.0  0.0   7196   356 pts/28   S+   20:12   0:00 sleep 180s

I give a SIGTERM to the process with id 22880 by using kill -15 22880 which kills the process. However, after this, I still see the sleep command running which exits after 180 seconds.

user 22881  0.0  0.0   7196   356 pts/28   S    20:12   0:00 sleep 180s

Why does this happen? What do I need to do to not leave the sleep 180s process running?


Solution

  • kill -15 22880 will send a signal to the shell executing the script, but not the sleep command. To send the signal to every process in the process group, you should be able to specify a negative process ID.

    kill -15 -22880
    

    Alternately, ensure that the script kills its children before exiting.

    trap 'kill $(jobs -p)' EXIT
    echo "Sleeping..."
    sleep 180s & wait
    

    If you leave sleep in the foreground when the signal is received, the shell must wait until it exits before running the trap; sleep is uninterruptible. The workaround is to run it in the background, then wait on it. wait, being a shell built-in, can be interrupted, so that the trap runs immediately and kills any background processes still in progress.