GPT on Question 14, Sep 27
I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?In Bash, the idiom is to track child PIDs and clean them up with an EXIT trap:
#!/usr/bin/env bash
children=()
cleanup() {
trap - EXIT
((${#children[@]})) || return
kill -TERM "${children[@]}" 2>/dev/null || true
wait "${children[@]}" 2>/dev/null || true
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
some_command &
children+=("$!")
another_command &
children+=("$!")
waitThis handles normal exit and catchable signals. It does not handle SIGKILL, crashes, or power loss—the parent cannot run cleanup after it is already dead.
For reliable cleanup in those cases:
- •Use a supervisor/cgroup, such as a systemd service with
KillMode=control-group(the default). This also catches grandchildren. - •On Linux, have each child set
prctl(PR_SET_PDEATHSIG, SIGTERM)beforeexec; Bash has no built-in way to do this, so a small wrapper is needed. - •If descendants must be terminated together, place them in a dedicated process group/session and have an external supervisor kill that group.
Avoid relying on pkill -P $$: it only finds immediate children, and once they are orphaned their PPID changes. Also avoid trap 'kill 0' EXIT unless the script owns a dedicated process group, since it can kill the invoking shell too.
Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
- Scored
- answered
- Received
- 2026-09-27 09:05:55 UTC
- Run
- 20260927T090007Z-7adb14
- Served by
- OpenAI · HTTP 200 · finish stop
- Size
- 1,307 characters · 1,739 tokens out incl. hidden reasoning · 25.7 s
In Bash, the idiom is to track child PIDs and clean them up with an `EXIT` trap:
```bash
#!/usr/bin/env bash
children=()
cleanup() {
trap - EXIT
((${#children[@]})) || return
kill -TERM "${children[@]}" 2>/dev/null || true
wait "${children[@]}" 2>/dev/null || true
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
some_command &
children+=("$!")
another_command &
children+=("$!")
wait
```
This handles normal exit and catchable signals. It does **not** handle `SIGKILL`, crashes, or power loss—the parent cannot run cleanup after it is already dead.
For reliable cleanup in those cases:
- Use a supervisor/cgroup, such as a systemd service with `KillMode=control-group` (the default). This also catches grandchildren.
- On Linux, have each child set `prctl(PR_SET_PDEATHSIG, SIGTERM)` before `exec`; Bash has no built-in way to do this, so a small wrapper is needed.
- If descendants must be terminated together, place them in a dedicated process group/session and have an external supervisor kill that group.
Avoid relying on `pkill -P $$`: it only finds immediate children, and once they are orphaned their PPID changes. Also avoid `trap 'kill 0' EXIT` unless the script owns a dedicated process group, since it can kill the invoking shell too.
End of response · 38 lines · 1,307 characters · sha256 33406fd92632bed1d9e8dbbbc9bf5e9abe2a85c1c47f776b96e4b44c457d5509