bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: kill $! won't kill the last command in asynchronous list


From: Chet Ramey
Subject: Re: kill $! won't kill the last command in asynchronous list
Date: Wed, 1 Apr 2020 14:59:05 -0400
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Thunderbird/68.5.0

On 4/1/20 12:16 PM, Oğuz wrote:
> Thanks for the reply.
> 
> 1 Nisan 2020 Çarşamba tarihinde Chet Ramey <address@hidden
> <mailto:address@hidden>> yazdı:
> 
>     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.
> 
> 
> You are right, I think I was just confused. But this is exactly where I'm
> stuck now;
> 1) I couldn't figure out how to get shell to kill the process it's waiting 
> for,

I think the only reliable way to do it is to use the process group.

> 2) kill -- -$! says no such process group is found; 

You have to start the job with job control enabled if you want the
background process to be its own process group leader, and at that point
the shell started to run the group command will not have job control
enabled and will run all processes in the same process group (its own),'
so you could in theory use $!.

If you start it from a shell with job control enabled, the bash running the
-c command will be in its own process group and be the process group
leader, and not have job control enabled.

> I couldn't figure out a
> reliable way to kill $! and its children. Sending signal to -$$ works most
> of the time, but $$ is not guaranteed to be the process group ID if I'm not
> mistaken.

See above about job control shells. The -c command shell is not
interactive, and will not have job control enabled by default, so all
processes in that command will be in the same process group, so if you can
figure out what it is, you should be fine. If you don't start that from a
shell with job control enabled, the process group will be difficult to
find, but $$ is your best bet and should work if you're starting it from
a job control shell.


> Should I ask this on a Q&A forum?

Different perspectives are always good. There are a lot of creative people
out there.

Chet

-- 
``The lyf so short, the craft so long to lerne.'' - Chaucer
                 ``Ars longa, vita brevis'' - Hippocrates
Chet Ramey, UTech, CWRU    address@hidden    http://tiswww.cwru.edu/~chet/



reply via email to

[Prev in Thread] Current Thread [Next in Thread]