I have a script which works great in bash 4.3, but gives me unexpected behavior with bash 3.2. Here's a simplified version:
set -o errexit -o pipefail
task() {
local name=${1}
local duration=${2}
trap 'echo "[${SECONDS} secs] ${name}: SIGINT"; exit 255' INT
echo "[${SECONDS} secs] ${name}: Running"
sleep "${duration}"
echo "[${SECONDS} secs] ${name}: Done"
}
trap 'echo "[${SECONDS} secs] SIGINT"; exit 255' INT
task 'Task 1' 5 &
task 'Task 2' 5 &
wait
echo "[${SECONDS} secs] Done"
Here's the output when run with bash 4.3 (4.3.42(1)-release) after CTRL-C'ing two seconds into it:
[0 secs] Task 1: Running
[0 secs] Task 2: Running
^C[2 secs] SIGINT
[2 secs] Task 2: SIGINT
[2 secs] Task 1: SIGINT
prompt>
Same thing but with bash 3.2 (3.2.57(1)-release):
[0 secs] Task 1: Running
[0 secs] Task 2: Running
^C[2 secs] SIGINT
prompt> [5 secs] Task 2: Done
[5 secs] Task 1: Done
Are there known issues preventing the above script from working correctly under bash 3.2? Do workarounds exist?
Here are a few things I've tried:
No signal handler in the parent:
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
No signal handlers at all:
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
Signal handler in parent that kills the process group with SIGINT (
kill -INT -- -$$
):[0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2 secs] Task 2: SIGINT [2 secs] Task 1: SIGINT prompt> [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT prompt> [5 secs] Task 2: Done [5 secs] Task 1: Done
Signal handler in parent that kill the process group with SIGTERM (tasks trap SIGTERM):
# bash 4.3 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT [2] 92813 terminated bash minimal_example.sh prompt> # bash 3.2 [0 secs] Task 1: Running [0 secs] Task 2: Running ^C[2 secs] SIGINT Terminated: 15 Terminated: 15 [2 secs] Task 2: SIGTERM [2 secs] Task 1: SIGTERM [1] 92836 terminated /bin/bash minimal_example.sh prompt>
The last is the closest to working properly in 3.2, but that same code behaves differently in 4.3.