GPT on Question 14, Sep 19
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?The idiomatic Bash approach is to run the work in a dedicated process group/session and kill that group from a trap:
#!/usr/bin/env bash
set -Eeuo pipefail
worker=
cleanup() {
local status=$?
trap - EXIT INT TERM HUP
if [[ -n ${worker:-} ]]; then
# Negative PID means “the process group whose PGID is $worker”.
kill -TERM -- "-$worker" 2>/dev/null || true
# Optional grace period, then force remaining descendants down.
sleep 2
kill -KILL -- "-$worker" 2>/dev/null || true
wait "$worker" 2>/dev/null || true
fi
exit "$status"
}
trap cleanup EXIT INT TERM HUP
# setsid makes this command the leader of a new session/process group.
setsid bash -c '
child_one &
child_two &
wait
' &
worker=$!
wait "$worker"Why a process group rather than pkill -P "$$":
- •
pkill -Ponly finds direct children. - •Grandchildren can be reparented as soon as an intermediate parent exits.
- •Signaling
-$workertargets all processes remaining in that process group.
Important limitation: traps do not run if the parent receives SIGKILL, crashes, or the machine goes down. If cleanup must also work in those cases, use an OS supervisor such as a systemd service/scope with KillMode=control-group. On Linux, a small wrapper using prctl(PR_SET_PDEATHSIG, ...) is another option, but that property must be set by each relevant child and has race/descendant considerations.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-19 09:05:58 UTC
- Run
- 20260919T090005Z-86161c
- Served by
- OpenAI · HTTP 200 · finish stop
- Size
- 1,460 characters · 887 tokens out incl. hidden reasoning · 15.9 s
The idiomatic Bash approach is to run the work in a dedicated process group/session and kill that group from a trap:
```bash
#!/usr/bin/env bash
set -Eeuo pipefail
worker=
cleanup() {
local status=$?
trap - EXIT INT TERM HUP
if [[ -n ${worker:-} ]]; then
# Negative PID means “the process group whose PGID is $worker”.
kill -TERM -- "-$worker" 2>/dev/null || true
# Optional grace period, then force remaining descendants down.
sleep 2
kill -KILL -- "-$worker" 2>/dev/null || true
wait "$worker" 2>/dev/null || true
fi
exit "$status"
}
trap cleanup EXIT INT TERM HUP
# setsid makes this command the leader of a new session/process group.
setsid bash -c '
child_one &
child_two &
wait
' &
worker=$!
wait "$worker"
```
Why a process group rather than `pkill -P "$$"`:
- `pkill -P` only finds direct children.
- Grandchildren can be reparented as soon as an intermediate parent exits.
- Signaling `-$worker` targets all processes remaining in that process group.
Important limitation: traps do not run if the parent receives `SIGKILL`, crashes, or the machine goes down. If cleanup must also work in those cases, use an OS supervisor such as a systemd service/scope with `KillMode=control-group`. On Linux, a small wrapper using `prctl(PR_SET_PDEATHSIG, ...)` is another option, but that property must be set by each relevant child and has race/descendant considerations.
End of response · 45 lines · 1,460 characters · sha256 a2dd327cc103ccda72970f31a5c595ed4cc1a9c2d52a8b3199e03eac1744c7be