Skip to content

Instantly share code, notes, and snippets.

@mrbar42
Last active October 20, 2024 09:27
Show Gist options
  • Save mrbar42/529cf0db529c0408ba1ef414653becdd to your computer and use it in GitHub Desktop.
Save mrbar42/529cf0db529c0408ba1ef414653becdd to your computer and use it in GitHub Desktop.
graceful exit for bash script with background children/subshells
#!/usr/bin/env bash
graceful_exit() {
# include this line: trap graceful_exit TERM INT HUP
echo "Exit requested..."
local timeout=${1:-4}
local list=""
for c in $(ps -o pid= --ppid $$); do
# request children shutdown
kill -0 ${c} 2>/dev/null && kill -TERM ${c} && list="$list $c" || true
done
if [ -n "$list" ]; then
# schedule hard kill after timeout
(sleep ${timeout}; kill -9 ${list} 2>/dev/null || true) &
local killer=${!}
wait ${list} 2>/dev/null || true
# children exited gracfully - cancel timer
sleep 0.5 && kill -9 ${killer} 2>/dev/null && list="" || true
fi
[ -z "$list" ] && echo "Exit Gracefully (0)" && exit 0 || echo "Dirty Exit (1)" && exit 1
}
# this line exectues when process exits
trap 'graceful_exit 5' TERM INT HUP
# simulate long tasks
sleep 60 &
echo "Started Task 1 ($!)"
sleep 60 &
echo "Started Task 2 ($!)"
echo "started Tasks - press Ctrl-C to stop them"
wait
echo "Normal exit"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment