help-bash
[Top][All Lists]
Advanced

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

Re: is kill 0 to be used to terminate the current script


From: alex xmb ratchev
Subject: Re: is kill 0 to be used to terminate the current script
Date: Tue, 21 Mar 2023 14:34:09 +0100

On Tue, Mar 21, 2023, 14:29 Greg Wooledge <greg@wooledge.org> wrote:

> On Tue, Mar 21, 2023 at 01:27:08PM +0100, alex xmb ratchev wrote:
> > On Tue, Mar 21, 2023, 12:58 Greg Wooledge <greg@wooledge.org> wrote:
> >
> > DESCRIPTION
> > >        The  kill()  system  call can be used to send any signal to any
> > > process
> > >        group or process.
> > >
> > >        If pid is positive, then signal sig is sent to the process with
> > > the  ID
> > >        specified by pid.
> > >
> > >        If pid equals 0, then sig is sent to every process in the
> process
> > > group
> > >        of the calling process.
>
> > that one , to send signal also to $( jobs -p ) ?
>
> You're basically asking how process groups work.  See below.
>

thanks in pre , mate , .. cant grok it at once
but yea thanks im sure its a big for me
text ya

> never seen , must be .c manual
>
> I pasted from "man 2 kill" on Linux.  I thought it was pretty obvious
> that it was a man page, from the formatting, and that it was in section 2,
> from the words "system call".
>
> OK, next, let's quote something from "man bash" regarding process groups:
>
>        To facilitate the implementation of the user interface to job
> control,
>        the operating system maintains the notion of a current terminal
> process
>        group ID.  Members of this process group (processes whose process
> group
>        ID is equal to the current terminal process group ID) receive
> keyboard-
>        generated signals such as SIGINT.  These processes are said  to
> be  in
>        the  foreground.
>
> After a bit more digging, I found "man 7 credentials" on Debian, which
> also talks about process groups:
>
>    Process group ID and session ID
>        Each process has a session ID and a process group ID, both
> represented
>        using  the  type pid_t.  A process can obtain its session ID using
> get‐
>        sid(2), and its process group ID using getpgrp(2).
>
>        A child created by fork(2) inherits its parent's session ID and
> process
>        group  ID.   A  process's session ID and process group ID are
> preserved
>        across an execve(2).
>
>        Sessions and process groups are abstractions devised to  support
> shell
>        job  control.   A process group (sometimes called a "job") is a
> collec‐
>        tion of processes that share the same process group ID; the shell
> cre‐
>        ates  a  new  process  group for the process(es) used to execute
> single
>        command or pipeline (e.g., the two processes  created  to  execute
> the
>        command  "ls | wc"  are placed in the same process group).  A
> process's
>        group membership can  be  set  using  setpgid(2).   The  process
> whose
>        process  ID  is  the  same as its process group ID is the process
> group
>        leader for that group.
>
> So.  We have a few concepts to explore here.  The first is this thing
> called a "process group ID".  Each process has one, but you don't normally
> see it in "ps" output, because it's not one of the default fields in either
> the "-f" or the "u" output format.  So we need to construct a special
> command to see them.
>
> unicorn:~$ ps -f
> UID          PID    PPID  C STIME TTY          TIME CMD
> greg        1010     999  0 Jan24 pts/2    00:00:00 bash
> greg      339327    1010  0 08:58 pts/2    00:00:00 ps -f
> unicorn:~$ ps -o uid,pid,ppid,pgid,tty,time,cmd
>   UID     PID    PPID    PGID TT           TIME CMD
>  1000    1010     999    1010 pts/2    00:00:00 bash
>  1000  339375    1010  339375 pts/2    00:00:00 ps -o
> uid,pid,ppid,pgid,tty,time
>
> Now that we know how to see the PGID, we can verify what credentials(7)
> is saying about pipelines.
>
> unicorn:~$ PS1='pts/2:\w\$ '
> pts/2:~$ sleep 100 | sleep 200 | grep foo
>
> unicorn:~$ PS1='pts/3:\w\$ '
> pts/3:~$ ps -t pts/2 -o pid,ppid,pgid,cmd
>     PID    PPID    PGID CMD
>    1010     999    1010 bash
>  339818    1010  339818 sleep 100
>  339819    1010  339818 sleep 200
>  339820    1010  339818 grep foo
>
> Using two terminal windows, I created a pipeline in one, and ran ps in
> the other, so that I could see the PIDs and PGIDs of the processes in
> the pipeline.  As promised, all the processes in the pipeline share
> the same PGID (339818).
>
> Therefore, if we wanted to kill the entire pipeline programatically (i.e.
> not by simply pressing Ctrl-C in pts/2), we could send a signal to the
> entire process group.  Remember this part from kill(2):
>
>        If pid is less than -1, then sig  is  sent  to  every  process  in
> the
>        process group whose ID is -pid.
>
> So, from pts/3 we could use this command:
>
>     kill -TERM -339818
>
> That would send a SIGTERM to each of the three processes in the process
> group (a.k.a. the pipeline).
>
> This leads to the next obvious question: how does a script get the process
> group ID of a pipeline?
>
> pts/2:~$ sleep 100 | sleep 200 | grep foo &
> [1] 340241
> pts/2:~$ echo "$!"
> 340241
>
> pts/3:~$ ps -t pts/2 -o pid,ppid,pgid,cmd
>     PID    PPID    PGID CMD
>    1010     999    1010 bash
>  340239    1010  340239 sleep 100
>  340240    1010  340239 sleep 200
>  340241    1010  340239 grep foo
>
> That $! value isn't the process group ID.  It's the PID of the last command
> in the pipeline.  To get the process group ID, we need to do more work.
>
> pts/3:~$ ps -p 340241 -o pgid=
>  340239
>
> So, that's one way we can get it.  Maybe there's something cleaner?
> No idea.
>
> Now, you asked:
>
> > that one , to send signal also to $( jobs -p ) ?
>
> pts/2:~$ sleep 500 | sleep 600 &
> [1] 340484
> pts/2:~$ sleep 700 | sleep 800 | sleep 900 &
> [2] 340490
> pts/2:~$ jobs -p
> 340483
> 340488
>
> It appears that "jobs -p" gives the process group IDs.  Interesting.  I
> didn't know that (it's not in "help jobs" either).  But that's really
> handy -- we can skip the PGID lookup.
>
> We can also take advantage of the fact that (jobs -p) in a subshell has
> special voodoo that lets it report the parent's jobs.
>
> pts/2:~$ mapfile -t jobs < <(jobs -p)
> pts/2:~$ declare -p jobs
> declare -a jobs=([0]="340483" [1]="340488")
>
> And then with a little shell magic:
>
> pts/2:~$ echo kill -TERM "${jobs[@]/#/-}"
> kill -TERM -340483 -340488
> pts/2:~$ kill -TERM "${jobs[@]/#/-}"
> pts/2:~$
> [1]-  Terminated              sleep 500 | sleep 600
> [2]+  Terminated              sleep 700 | sleep 800 | sleep 900
>
>


reply via email to

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