Search code examples
linuxbashscriptingsignalschildren

Kill bash script foreground children when a signal comes


I am wrapping a fastcgi app in a bash script like this:

#!/bin/bash
# stuff
./fastcgi_bin
# stuff

As bash only executes traps for signals when the foreground script ends I can't just kill -TERM scriptpid because the fastcgi app will be kept alive.
I've tried sending the binary to the background:

#!/bin/bash
# stuff
./fastcgi_bin &
PID=$!
trap "kill $PID" TERM
# stuff

But if I do it like this, apparently the stdin and stdout aren't properly redirected because it does not connect with lighttpds mod_fastgi, the foreground version does work.

EDIT: I've been looking at the problem and this happens because bash redirects /dev/null to stdin when a program is launched in the background, so any way of avoiding this should solve my problem as well.

Any hint on how to solve this?


Solution

  • There are some options that come to my mind:

    • When a process is launched from a shell script, both belong to the same process group. Killing the parent process leaves the children alive, so the whole process group should be killed. This can be achieved by passing the negated PGID (Process Group ID) to kill, which is the same as the parent's PID. ej: kill -TERM -$PARENT_PID

    • Do not execute the binary as a child, but replacing the script process with exec. You lose the ability to execute stuff afterwards though, because exec completely replaces the parent process.

    • Do not kill the shell script process, but the FastCGI binary. Then, in the script, examine the return code and act accordingly. e.g: ./fastcgi_bin || exit -1

    Depending on how mod_fastcgi handles worker processes, only the second option might be viable.