GPT on Question 14, Sep 15
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?The idiomatic approach is to have the parent clean up via trap, rather than having children poll $PPID.
#!/usr/bin/env bash
set -Eeuo pipefail
children=()
cleanup() {
status=$?
trap - EXIT INT TERM HUP
if ((${#children[@]})); then
kill -TERM -- "${children[@]}" 2>/dev/null || true
wait "${children[@]}" 2>/dev/null || true
fi
exit "$status"
}
trap cleanup EXIT INT TERM HUP
some_command &
children+=("$!")
another_command &
children+=("$!")
waitThis handles normal exit and catchable signals. It cannot handle the parent being killed with SIGKILL, crashing before cleanup, or the machine losing power.
For entire descendant trees, use a dedicated process group/session or, preferably, a supervisor/cgroup:
- •systemd service:
KillMode=control-groupensures all service processes are terminated. - •Containers/cgroups: terminate the whole cgroup.
- •Linux child-side guarantee: use a small wrapper that calls
prctl(PR_SET_PDEATHSIG, SIGTERM)beforeexec. Bash has no built-in equivalent.
Avoid periodically checking $PPID == 1; orphaned processes may be reparented to a subreaper rather than PID 1, and such polling is inherently racy.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-15 09:06:14 UTC
- Run
- 20260915T090004Z-599f39
- Served by
- OpenAI · HTTP 200 · finish stop
- Size
- 1,219 characters · 816 tokens out incl. hidden reasoning · 13.0 s
The idiomatic approach is to have the parent clean up via `trap`, rather than having children poll `$PPID`.
```bash
#!/usr/bin/env bash
set -Eeuo pipefail
children=()
cleanup() {
status=$?
trap - EXIT INT TERM HUP
if ((${#children[@]})); then
kill -TERM -- "${children[@]}" 2>/dev/null || true
wait "${children[@]}" 2>/dev/null || true
fi
exit "$status"
}
trap cleanup EXIT INT TERM HUP
some_command &
children+=("$!")
another_command &
children+=("$!")
wait
```
This handles normal exit and catchable signals. It cannot handle the parent being killed with `SIGKILL`, crashing before cleanup, or the machine losing power.
For entire descendant trees, use a dedicated process group/session or, preferably, a supervisor/cgroup:
- **systemd service:** `KillMode=control-group` ensures all service processes are terminated.
- **Containers/cgroups:** terminate the whole cgroup.
- **Linux child-side guarantee:** use a small wrapper that calls `prctl(PR_SET_PDEATHSIG, SIGTERM)` before `exec`. Bash has no built-in equivalent.
Avoid periodically checking `$PPID == 1`; orphaned processes may be reparented to a subreaper rather than PID 1, and such polling is inherently racy.
End of response · 39 lines · 1,219 characters · sha256 da99e6ad03b9bf3997077d6631e99ff475b64f24eda60137dd3baa64644d2a93