Gemini on Question 14, Sep 30
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?The most idiomatic way to handle this in Bash is by using a trap on the EXIT signal.
When you trap EXIT, Bash guarantees the cleanup code will run whether the script finishes normally, errors out, or is killed by standard signals like SIGINT (Ctrl+C) or SIGTERM. (Note: Nothing can catch SIGKILL / kill -9).
There are two primary ways to do this, depending on whether your script spawns simple children or deep process trees (grandchildren).
1. The Standard Way: Kill immediate background jobs
If your script just spawns a few background processes using &, the most idiomatic approach is to use jobs -p to get their Process IDs (PIDs) and kill them.
#!/bin/bash
# Define the cleanup function
cleanup() {
# Suppress error if no jobs are running
kill $(jobs -p) 2>/dev/null || true
echo "Parent exiting. Orphaned children purged."
}
# Trap the EXIT signal
trap cleanup EXIT
# --- Your script logic here ---
echo "Starting child processes..."
sleep 100 &
sleep 200 &
# Wait for children to finish (or until script is killed)
wait2. The Robust Way: Kill the Process Group (Grandchildren too)
If your child processes spawn their own children, jobs -p won't be enough because it only knows about direct children. In this case, you should kill the entire Process Group.
In Bash, sending a signal to PID 0 sends that signal to all processes in the current process group.
#!/bin/bash # Trap EXIT to kill the entire process group trap 'kill 0' EXIT # --- Your script logic here --- echo "Starting complex child processes..." (sleep 100 && echo "done") & bash -c 'sleep 200' & wait
⚠️ Crucial Warning for kill 0:
Do not run a script using kill 0 by sourcing it (source ./script.sh or . ./script.sh). If you do, the script runs in the process group of your current terminal session, and kill 0 will forcefully close your terminal and log you out! Always run it as an executable (./script.sh).
Summary of Best Practices
- 1.Always trap
EXIT: Don't try to trapSIGINTandSIGTERMindividually unless you have a specific reason. TrappingEXITacts as a catch-all for both normal terminations and caught signals. - 2.Use
wait: If your script is just a supervisor for background tasks, putwaitat the end of the script. This suspends the parent script until the children finish, but allows thetrapto fire if the parent is interrupted. - 3.Redirect
stderr: When killing jobs during cleanup, always append2>/dev/null. If the children have already finished gracefully by the time the script exits,killwill complain about non-existent PIDs.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-30 09:07:08 UTC
- Run
- 20260930T090007Z-45ce12
- Served by
- Google · HTTP 200 · finish stop
- Size
- 2,683 characters · 1,948 tokens out incl. hidden reasoning · 18.1 s
End of response · 57 lines · 2,683 characters · sha256 deb583a672aa10d933e17bb21616df018095be03bf6ffd8aca1640be785334c5