Gemini on Question 14, Sep 13
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?The idiomatic way to handle this in Bash is to use the trap command combined with a pseudo-signal called EXIT. This ensures your cleanup code runs whether the script finishes normally, errors out, or is interrupted (like with Ctrl+C).
Here is the standard, safest way to do it, along with a more aggressive approach if you are dealing with complex process trees.
Method 1: The Standard Way (Direct Children)
If your script spawns background processes using the & operator, the safest and most idiomatic way to kill them is using jobs -p. This ensures you only kill processes directly started by your script.
#!/usr/bin/env bash
# Define the cleanup function
cleanup() {
echo "Parent dying: Purging orphaned children..."
# Get all background job PIDs and kill them.
# Redirect stderr to /dev/null to hide errors if they are already dead.
local child_pids=$(jobs -p)
if [[ -n "$child_pids" ]]; then
kill $child_pids 2>/dev/null
fi
}
# Register the cleanup function to run on EXIT
trap cleanup EXIT
# --- Your script logic below ---
echo "Starting children..."
sleep 100 &
sleep 200 &
echo "Doing some work..."
sleep 2
# When the script ends (or you press Ctrl+C), 'cleanup' will run automatically.Method 2: The Aggressive Way (Children & Grandchildren)
The limitation of jobs -p is that it only knows about direct children. If your child process spawns its own children (grandchildren of your script), jobs -p will leave the grandchildren orphaned.
If you are on Linux, you can use pkill to target all processes that have your script ($$) as their parent.
#!/usr/bin/env bash
cleanup() {
echo "Purging entire child tree..."
# Kill all processes where the Parent PID (-P) is this script ($$)
pkill -P $$
}
trap cleanup EXIT
# ... script logic ...Method 3: The Process Group Way (Advanced)
If you want to ensure the absolute destruction of every child, grandchild, and great-grandchild, you can kill the entire Process Group.
By sending a signal to a negative PID (e.g., -$$), you send it to the whole process group.
Note: This is powerful but requires a safety check. If you run this script via source in your terminal, the process group is your terminal, and it will close your terminal window!
#!/usr/bin/env bash
cleanup() {
# Trap SIGTERM to default behavior so we don't loop indefinitely
trap - TERM
# Kill the entire process group, ignoring errors if some are already dead
# $$ is the script's PID. -$$ targets its process group.
kill -- -$$ 2>/dev/null
}
trap cleanup EXIT INT TERM
# ... script logic ...Summary of Best Practices:
- 1.Always use
trap ... EXIT. It acts as a standardfinallyblock in Bash. - 2.Default to
jobs -p(Method 1) because it is standard POSIX (works on macOS/BSD too) and carries zero risk of accidentally killing the wrong processes. - 3.Suppress errors with
2>/dev/null. If a child process finishes before the parent dies,killwill throw a "No such process" error. Suppressing it keeps your terminal output clean.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-13 09:05:45 UTC
- Run
- 20260913T090021Z-a7390a
- Served by
- Google · HTTP 200 · finish stop
- Size
- 3,154 characters · 2,422 tokens out incl. hidden reasoning · 20.5 s
End of response · 82 lines · 3,154 characters · sha256 ccaa4ad1b470f6dd76c20d4912775133c800d7e6559a6838a910922378799788