I'm trying to set up a shell script so that it runs background processes, and when I ctrl+C the shell script, it kills the children, then exits.
The best that I've managed to come up with is this. It appears that kill 0 -INT
also kills the script before the wait happens, so the shell script dies before the children complete.
Any ideas on how I can make this shell script wait for the children to die after sending INT?
#!/bin/bash
trap 'killall' INT
killall() {
echo **** Shutting down... ****
kill 0 -INT
wait # Why doesn't this wait??
echo DONE
}
process1 &
process2 &
process3 &
cat # wait forever
Best Answer
First, you should know that
kill 0
send the signal to all process in current process group. (see kill(1) - Linux man page) My guess is that it is killing more than it should. This is whywait
is not waiting, it is being terminated for some reason. My best bet to solve this problem is to iterate over running jobs fromjobs -pr
killing one by one: this way I assure the signal is sent only to child processes in that moment and nothing more.To get this to work I did several tests, but I was stuck on sending SIGINT to child processes. They simple don't react to it! Searching the web I've found this answer on Stack Overflow:
https://stackoverflow.com/questions/2524937/how-to-send-a-signal-sigint-from-script-to-script-bash
So the real problem is that you cannot send SIGINT from one script to other, because in non-interactive shells the signal is ignored. I was not able to workaround this issue (using
bash -i
to call the child script does not to work).I know you probably want to send SIGINT and wait for the child processes to shutdown gracefully, but if you do not mind to use SIGTERM (or any other signal but SIGINT) this is the best script I wrote:
To test, I've created this
long.sh
script:In this last script I did not use
sleep
function because it creates a new process that was staying on memory even after the script finishes. In your script, you can call new processes but you should assure to broadcast the SIGTERM (or any other signal you've used) to all of them.