Is there any way to invoke a subprocess so that it and all its descendants are sent an interrupt, just as if you Ctrl-C a foreground task? I’m trying to kill a launcher script that invokes a long-running child. I’ve tried kill -SIGINT $child (which doesn’t send the interrupt to its descendants so is a no-op) and kill -SIGINT -$child (which works when invoked interactively but not when running in a script).
Here’s a test script. The long-running script is test.sh --child. When you call test.sh --parent, it invokes test.sh --child & and then tries to kill it. How can I make the parent kill the child successfully?
#!/bin/bash
if [ "$1" = "--child" ]; then
sleep 1000
elif [ "$1" = "--parent" ]; then
"$0" --child &
for child in $(jobs -p); do
echo kill -SIGINT "-$child" && kill -SIGINT "-$child"
done
wait $(jobs -p)
else
echo "Must be invoked with --child or --parent."
fi
I know that you can modify the long-running child to trap signals, send them to its subprocess, and then wait (from
Bash script kill background (grand)children on Ctrl+C), but is there any way without modifying the child script?
Read this : How to send a signal SIGINT from script to script ? BASH
Also from
info bashSo
bashdifferentiates background processes from foreground processes by the process group ID. If the process group id is equal to process id, then the process is a foreground process, and will terminate when it receives aSIGINTsignal. Otherwise it will not terminate (unless it is trapped).You can see the process group Id with
Thus, when you run a background process (with
&) from within a script, it will ignore theSIGINTsignal, unless it is trapped.However, you can still kill the child process with other signals, such as
SIGKILL,SIGTERM, etc.For example, if you change your script to the following it will successfully kill the child process:
Output: