On 4/1/20 12:19 AM, Oğuz wrote: > $ bash -c '{ sleep 15; } & pstree -p $!; kill $!; echo $?' > bash(6955)───sleep(6959) > 0 > $ pkill -e sleep > sleep killed (pid 6959) > > As seen above, kill $! doesn't kill `sleep` if it's enclosed in curly > braces. Dropping curly braces, or execing sleep (e.g `{ exec sleep 15; }`) > fixes this problem, but I didn't understand why.
The braces enclose a group command, and that group command is what's started in the background. That process is effectively a copy of the shell that runs the command list contained in the group command (there can be more than one command, though your example doesn't include that). Since that shell is what's forked to execute the command list, it's the process whose pid ends up in $! and the one that receives the SIGTERM. Unless the shell kills the process it's waiting for when it receives the SIGTERM, or you send the signal to the entire process group, sleep won't see it. There are various race condition here. Shells always ignore SIGTERM. One of the first things a subshell does after the shell forks it is reset the SIGTERM handler to SIG_DFL. If the background process doesn't run until the rest of the parent's command list executes, the parent will send a SIGTERM to a process that's still ignoring it. It's also possible that the SIGTERM arrives before the sleep is executed and kills the shell, so the sleep never runs at all. Under most circumstances, but not all, I would expect the shell to be killed and the sleep to survive. -- ``The lyf so short, the craft so long to lerne.'' - Chaucer ``Ars longa, vita brevis'' - Hippocrates Chet Ramey, UTech, CWRU c...@case.edu http://tiswww.cwru.edu/~chet/