[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
>
>