How can bash script do the equivalent of Ctrl-C to a background task?
Solution 1:
For anyone wondering, this is how you launch childs in the background and kill them on ctrl+c:
#!/usr/bin/env bash
command1 &
pid[0]=$!
command2 &
pid[1]=$!
trap "kill ${pid[0]} ${pid[1]}; exit 1" INT
wait
Solution 2:
Read this : How to send a signal SIGINT from script to script ? BASH
Also from info bash
To facilitate the implementation of the user interface to job control,
the operating system maintains the notion of a current terminal process
group ID. Members of this process group (processes whose process group
ID is equal to the current terminal process group ID) receive keyboard-
generated signals such as SIGINT. These processes are said to be in
the foreground. Background processes are those whose process group ID
differs from the terminal's; such processes are immune to keyboard-gen‐
erated signals.
So bash
differentiates 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 a SIGINT
signal. Otherwise it will not terminate (unless it is trapped).
You can see the process group Id with
ps x -o "%p %r %y %x %c "
Thus, when you run a background process (with &
) from within a script, it will ignore the SIGINT
signal, 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:
#!/bin/bash
if [ "$1" = "--child" ]; then
sleep 1000
elif [ "$1" = "--parent" ]; then
"$0" --child &
for child in $(jobs -p); do
echo kill "$child" && kill "$child"
done
wait $(jobs -p)
else
echo "Must be invoked with --child or --parent."
fi
Output:
$ ./test.sh --parent
kill 2187
./test.sh: line 10: 2187 Terminated "$0" --child
Solution 3:
somecommand &
returns a pid of the child in $!
somecommand &
pid[0]=$!
anothercommand &
pid[1]=$!
trap "kill ${pid[0]} ${pid[1]}; exit 1" INT
wait
I would start with this model rather than with bash job control (bg, fg, jobs). Normally init inherits and reaps orphan processes. What problem are you trying to solve?