MODELDRIFT.WATCH

Question 14 · Sep 12 · Day 3

GPT on Question 14, Sep 12

I'm writing a bash script to purge orphaned children after the parent dies. What's the idiomatic way?

A dead Bash process cannot clean up its children. The idiomatic solution depends on how reliably you need this to work.

Normal exits and catchable signals

Track child PIDs and clean them up with an EXIT trap:

#!/usr/bin/env bash

children=()

cleanup() {
    status=$?
    trap - EXIT INT TERM HUP

    if ((${#children[@]})); then
        kill -TERM "${children[@]}" 2>/dev/null || :
        wait "${children[@]}" 2>/dev/null || :
    fi

    exit "$status"
}

trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM

worker1 & children+=("$!")
worker2 & children+=("$!")

wait

This handles normal exit, errors, and HUP/INT/TERM. It does not handle SIGKILL, a kernel crash, or descendants spawned by those children.

Avoid blindly using:

trap 'kill 0' EXIT

It signals the entire current process group and may kill the invoking shell or unrelated processes unless the script is deliberately running in its own session/process group.

Reliable whole-tree cleanup

For production use, run the script under a supervisor that owns a cgroup, such as systemd:

[Service]
ExecStart=/path/to/script
KillMode=control-group

Then stopping or losing the service kills all processes in its cgroup, including grandchildren.

On Linux, another option is a small launcher that sets prctl(PR_SET_PDEATHSIG, SIGTERM) in each child, but Bash has no built-in portable equivalent. If cleanup must also work when the parent receives SIGKILL, use systemd/cgroups or another external supervisor.

sha256 8c6575650e5e… · 27 tokens in · 906 out · 16.2 s · via OpenAI · stopped on its own

Sep 12, the whole dayQuestion 14, every day

Exact recordShowHideThe model id, the run, the verbatim text with line numbers and its full sha256
Model
openai/gpt-5.6-sol
pinned openai/gpt-5.6-sol-20260709; alias resolved to openai/gpt-5.6-sol-20260709 at 2026-09-12 09:00:20 UTC (matches the pin)
Date
2026-09-12 · run 20260912T090021Z-c0c86e · scorer v1
Scored
answered
Changes
Minor Reverted latency anomaly: went back to its usual response time on a question about cleaning up orphaned child processes in bash
sha256
8c6575650e5e40a75d7cd9af5a539af0609f30fdff1c4d07eb22a9160c78f0dc
Permalink
https://modeldrift.watch/r/2026-09-12/R5/openai/gpt-5.6-sol/
Scored
answered
Received
2026-09-12 09:06:06 UTC
Run
20260912T090021Z-c0c86e
Served by
OpenAI · HTTP 200 · finish stop
Size
1,562 characters · 906 tokens out incl. hidden reasoning · 16.2 s
A dead Bash process cannot clean up its children. The idiomatic solution depends on how reliably you need this to work.
### Normal exits and catchable signals
Track child PIDs and clean them up with an `EXIT` trap:
```bash
#!/usr/bin/env bash
children=()
cleanup() {
status=$?
trap - EXIT INT TERM HUP
if ((${#children[@]})); then
kill -TERM "${children[@]}" 2>/dev/null || :
wait "${children[@]}" 2>/dev/null || :
fi
exit "$status"
}
trap cleanup EXIT
trap 'exit 129' HUP
trap 'exit 130' INT
trap 'exit 143' TERM
worker1 & children+=("$!")
worker2 & children+=("$!")
wait
```
This handles normal exit, errors, and `HUP`/`INT`/`TERM`. It does **not** handle `SIGKILL`, a kernel crash, or descendants spawned by those children.
Avoid blindly using:
```bash
trap 'kill 0' EXIT
```
It signals the entire current process group and may kill the invoking shell or unrelated processes unless the script is deliberately running in its own session/process group.
### Reliable whole-tree cleanup
For production use, run the script under a supervisor that owns a cgroup, such as systemd:
```ini
[Service]
ExecStart=/path/to/script
KillMode=control-group
```
Then stopping or losing the service kills all processes in its cgroup, including grandchildren.
On Linux, another option is a small launcher that sets `prctl(PR_SET_PDEATHSIG, SIGTERM)` in each child, but Bash has no built-in portable equivalent. If cleanup must also work when the parent receives `SIGKILL`, use systemd/cgroups or another external supervisor.

End of response · 57 lines · 1,562 characters · sha256 8c6575650e5e40a75d7cd9af5a539af0609f30fdff1c4d07eb22a9160c78f0dc