The tini init-process, used in Docker, mentions that process group killing is not activated by default and gives the following example:
docker run krallin/ubuntu-tini sh -c 'sleep 10'
If I run this, and press Ctrl-C immediately after, I indeed have to wait for 10 seconds till the child process exits.
However, if instead of sh
I used bash
:
docker run krallin/ubuntu-tini bash -c 'sleep 10'
and press Ctrl-C, the process exits immediately.
Why do sh
(which is symlinked to dash
) and bash
behave differently towards this child process?
And how does Bash kill the child process, I thought Bash does not propagate signals by default?
Answered thanks to chepner and Charles Duffy:
bash -c
has an implicit optimization where it uses exec
to replace itself if possible. sh
(dash
) does not have this optimization. See also this observation.
To verify:
bash
:❯ docker run --name test --rm --detach krallin/ubuntu-tini bash -c 'sleep 60'
03194d48a4dcc8225251fe1e5de2dcbb901c8a9cfd0853ae910bfe4d3735608d
❯ docker exec test ps axfo pid,ppid,args
PID PPID COMMAND
1 0 /usr/bin/tini -- bash -c sleep 60
7 1 sleep 60
sh
:❯ docker run --name test --rm --detach krallin/ubuntu-tini sh -c 'sleep 60'
e56f207509df4b0b57f8e6b2b2760835f6784a147b200d798dffad112bb11d6a
❯ docker exec test ps axfo pid,ppid,args
PID PPID COMMAND
1 0 /usr/bin/tini -- sh -c sleep 60
7 1 sh -c sleep 60
8 7 \_ sleep 60