Gemini on Question 14, Sep 29
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 using the trap command bound to the EXIT pseudo-signal.
When you trap EXIT, Bash guarantees that the trap will run whether the script finishes normally, errors out, or is killed by standard signals (like SIGTERM or SIGINT / Ctrl+C).
Here are the two best approaches depending on your script's architecture.
Approach 1: The Safe Way (Kill only background jobs)
If your script explicitly spawns background processes using &, you can use jobs -p to get their Process IDs and kill them.
#!/bin/bash
# Define a cleanup function
cleanup() {
# Get PIDs of all background jobs started by this script
local pids=$(jobs -p)
if [[ -n "$pids" ]]; then
echo "Cleaning up orphaned children..."
kill $pids 2>/dev/null
fi
}
# Trap the EXIT signal
trap cleanup EXIT
# --- Your script logic below ---
echo "Starting parent script..."
sleep 100 & # Child 1
sleep 200 & # Child 2
# Wait for all background jobs to finish
waitWhy this is idiomatic: It is clean, predictable, and only targets processes explicitly tracked by the current shell's job control.
Approach 2: The "Nuclear" Way (Kill the process group)
If your script spawns complex trees of processes (children spawning grandchildren), jobs -p might not catch the grandchildren. In this case, you can send a signal to the entire process group using kill 0.
#!/bin/bash # Trap EXIT and send SIGTERM to the entire process group trap 'trap - EXIT; kill 0' EXIT # --- Your script logic below --- echo "Starting parent script..." # This child spawns a grandchild (sleep 100 && echo "done") & wait
Warning: kill 0 kills everything sharing the script's Process Group ID. This is usually fine for a standalone script, but do not use this if your script is sourced into an interactive terminal, as it will kill the user's terminal session. (Notice trap - EXIT is used to prevent an infinite loop of signals).
The Unavoidable Caveat: kill -9 (SIGKILL)
Bash cannot trap SIGKILL. If your parent script is killed with kill -9, the OS forcefully destroys the parent before Bash can execute the trap. In this scenario, the children will become orphaned.
If you must guarantee that children die even if the parent receives a SIGKILL, you cannot rely purely on Bash. You must rely on the Linux kernel.
Here are the two ways to handle the kill -9 scenario:
1. Using systemd (Modern Linux Standard)
Wrap your script execution in systemd-run. This puts the script and all its children into a temporary cgroup. If the parent dies, systemd cleans up the entire cgroup.
systemd-run --user --scope ./your_script.sh
2. Using prctl (Parent Death Signal)
Linux has a feature where a child can ask the kernel to send it a signal if its parent dies. You can use the standard prlimit (or pdeathsig wrappers) to launch the children:
# PR_SET_PDEATHSIG is standard on Linux # This forces sleep to receive a SIGTERM if this bash script dies for ANY reason perl -e 'require "syscall.ph"; syscall(&SYS_prctl, 1, 15, 0, 0, 0); exec @ARGV' sleep 100 &
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-29 09:06:52 UTC
- Run
- 20260929T090007Z-334891
- Served by
- Google · HTTP 200 · finish stop
- Size
- 3,193 characters · 2,407 tokens out incl. hidden reasoning · 20.4 s
End of response · 77 lines · 3,193 characters · sha256 15e7e2b2d49f0f9f3ece5f86a8b967ea9b327c17393d86ad09d150e9d75ab927