shell script to spawn processes, terminate children on SIGTERM
Asked Answered
C

4

11

I want to write a shell script that spawns several long-running processes in the background, then hangs around. Upon receiving SIGTERM, I want all the subprocesses to terminate as well.

Basically, I want a "master process".

Here's what I got so far:

#!/bin/sh

sleep 600 &
PID1="$!"

sleep 600 &
PID2="$!"

# supposedly this should kill the child processes on SIGTERM. 
trap "kill $PID1 $PID2" SIGTERM 

wait

The above script fails with trap: 10: SIGTERM: bad trap.

Edit: I'm using Ubuntu 9.04

Cosmetician answered 10/6, 2009 at 14:48 Comment(0)
C
5

Joe's answer put me on the right track. I also found out I should trap more signals to cover my bases.

Final script looks like this:

#!/bin/sh

sleep 600 &
PID1="$!"

sleep 600 &
PID2="$!"

trap "kill $PID1 $PID2" exit INT TERM

wait
Cosmetician answered 10/6, 2009 at 15:27 Comment(2)
If you think you have to use signal numbers, you should only use the standardized ones. But I siggest to use your system's signal names instead.Adeleadelheid
Well, it's your code, you can have as many versions as wanted ;-)Adeleadelheid
L
13

This works for me:

trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT
  • kill -- -$$ sends a SIGTERM to the whole process group, thus killing also descendants.

  • Specifying signal EXIT is useful when using set -e (more details here).

Landmark answered 31/1, 2010 at 21:25 Comment(3)
What does pid 0 mean? And do you mean the ... literally, or as a placeholder?Cosmetician
Somehow this only worked for me when I used kill -- 0 in place of kill -- -$$. The latter said 11641: no process found for some reason.Thespian
trap "trap - TERM && kill -- -$$" INT TERM EXIT for us POSIX aficionados.Overeager
C
5

Joe's answer put me on the right track. I also found out I should trap more signals to cover my bases.

Final script looks like this:

#!/bin/sh

sleep 600 &
PID1="$!"

sleep 600 &
PID2="$!"

trap "kill $PID1 $PID2" exit INT TERM

wait
Cosmetician answered 10/6, 2009 at 15:27 Comment(2)
If you think you have to use signal numbers, you should only use the standardized ones. But I siggest to use your system's signal names instead.Adeleadelheid
Well, it's your code, you can have as many versions as wanted ;-)Adeleadelheid
A
4

I suspect your /bin/sh is not a Bash (though you tagged the question as 'Bash').

From the message I guess it's a DASH. Check its manual or just fix your shebang if you need to write Bash code.

Adeleadelheid answered 10/6, 2009 at 15:26 Comment(0)
I
1

This script looks correct and works for me as expected.

How do you send the SIGTERM signal to the "master process"? Maybe you should execute kill -l to check which signals are supported. As the error message suggests you send signal "10" which your system doesn't seem to recognize.

And next time you should add operating system, shell version, kernel, ... for such a question

Intonate answered 10/6, 2009 at 15:17 Comment(1)
Thanks for the response. I'm using Ubuntu 9.04, and reading your answer I realized this was probably a bash vs. dash thing. It indeed works as advertised if I change the first line to #!/bin/bashCosmetician

© 2022 - 2024 — McMap. All rights reserved.