Gemini on Question 14, Sep 16
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?The idiomatic way to handle cleanup in a Bash script when it exits (or dies) is to use the trap command tied to the EXIT pseudo-signal.
Here are the two most common and safest approaches, depending on how your script spawns children.
1. The Built-in Way (Using Job Control)
If your script spawns processes in the background using &, the safest and most idiomatic way is to kill them using Bash's built-in jobs -p command. This ensures you only kill processes directly started by your script.
#!/bin/bash
# Define the cleanup function
cleanup() {
echo "Parent exiting, purging children..."
# Get all background job PIDs and kill them.
# Suppress errors in case some have already finished.
kill $(jobs -p) 2>/dev/null
}
# Trap the EXIT signal
trap cleanup EXIT
# --- Your script logic below ---
echo "Starting background workers..."
sleep 100 &
sleep 200 &
# Simulate doing some work, then crashing or exiting
sleep 2
echo "Done."Why this is good:
- •
trap ... EXITfires whether the script exits normally, crashes due to a syntax error, or receives a termination signal likeSIGINT(Ctrl+C) orSIGTERM. - •
jobs -pis a Bash built-in, so it doesn't rely on external tools.
2. The pkill Way (For deeper process trees)
If your children spawn their own children (grandchildren) or detach from Bash's job control, jobs -p might not be enough. You can use pkill to target any process whose Parent PID (PPID) is your script's PID ($$).
#!/bin/bash trap 'pkill -P $$' EXIT # --- Your script logic below --- sleep 100 & sleep 200 & sleep 2
Note: pkill -P $$ only kills direct children. If you need to kill an entire process tree (grandchildren included), it gets significantly more complex in plain Bash.
Advanced: The Process Group Way (Kill Everything)
If you want to absolutely ensure that every child and grandchild process spawned by your script dies, you can kill the entire process group by sending a signal to PID 0.
Warning: You must enable job control (set -m) so your script gets its own process group, otherwise kill 0 might kill your terminal session or SSH connection!
#!/bin/bash set -m # Enable job control so this script gets its own process group trap 'kill -- -$$ 2>/dev/null' EXIT sleep 100 & sleep 200 & sleep 2
The Unavoidable Caveat: SIGKILL (kill -9)
No matter how perfectly you write your trap, it cannot catch SIGKILL (kill -9).
If the OOM (Out of Memory) killer or an angry sysadmin sends kill -9 to your parent script, it will die instantly, the trap will not execute, and the children will be orphaned.
If preventing orphans in a kill -9 scenario is absolutely critical, you cannot rely entirely on Bash. You would need to use a Linux-specific feature called prctl(PR_SET_PDEATHSIG, ...), which forces the kernel to send a signal to a child when its parent dies. Because Bash cannot make system calls easily, this is usually done by wrapping your child commands in a tiny Python, Perl, or C script.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-16 09:07:08 UTC
- Run
- 20260916T090004Z-fdcf7b
- Served by
- Google · HTTP 200 · finish stop
- Size
- 3,088 characters · 2,067 tokens out incl. hidden reasoning · 19.6 s
End of response · 74 lines · 3,088 characters · sha256 5716c706ca19888940d2272f59eff3fe14ef1013ff9be06af923cbb7ecba0185