help-bash
[Top][All Lists]
Advanced

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

Re: [Help-bash] Where the complete behavior of & is documented?


From: Chet Ramey
Subject: Re: [Help-bash] Where the complete behavior of & is documented?
Date: Sat, 24 Feb 2018 14:17:41 -0500
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:52.0) Gecko/20100101 Thunderbird/52.5.2

On 2/23/18 4:11 PM, Peng Yu wrote:

> When I check the processes, I see
> 
> $ ps -f | grep 49839 |head -n 2
>   504 49839 48607   0  2:50PM ttys021    0:00.04 bash ./main1.sh
>   504 49840 49839   0  2:50PM ttys021    0:00.02 awk -e BEGIN {
> for(i=0;;i++) { system("sleep 5"); print i } }
> 
> Now, once I type ^C at the terminal running ./main1.sh, I don't find
> the process 49839 anymore.
> 
> Running `jobs` in this terminal, show no jobs running in the
> background despite 49840 is still running. Note that the pid of the
> parent of 49840 becomes 1.
> 
> $ ps -f | grep 49840 | head -n 2
>   504 49840     1   0  2:50PM ttys021    0:00.03 awk -e BEGIN {
> for(i=0;;i++) { system("sleep 5"); print i } }
>   504 50005 49840   0  2:52PM ttys021    0:00.01 sleep 5
> 
> Then, when I type `exit` in the terminal used to run ./main1.sh, the
> awk process 49840 will be terminated as well.
> 
> This means that somehow, bash understand the difference between the
> processing running main1.sh and the terminal process from which
> main1.sh is called.
> 
> But how does bash know to kill awk upon exit, since the parent pid of
> the awk process is 1. It sounds like bash shouldn't know it. So this
> is confusing to me.

This is the premise that results in your faulty conclusion.

When you ^C the script, that kills the script. But since the awk process
was started in the background when job control was not active, it ignores
SIGINT, as documented.

The script was started from an interactive shell with job control enabled,
and the script does not have job control enabled, so all of the processes
started from the script, including the awk command, are in the same process
group, and the process interpreting the script is the process group leader.

When that process gets killed, not only does the awk command get orphaned
and reparented to init (process 1), it becomes the only member of the
process group. The process still has a parent in another process group that
can conceivably control it, so the process group itself is not orphaned,
though the awk process is. Orphaned process groups are the key.

All processes that share the same controlling terminal are members of the
same `session'. In your case, the controlling terminal is the terminal
emulator (xterm or whatever) you ran the script from -- it's what you talk
to when you open /dev/tty. The interactive shell (or the xterm process
itself, it doesn't make a practical difference) is called the `controlling
process' or `session leader'.

So the awk process is orphaned. But the process group?

The session leader (the interactive shell) exits, and the terminal emulator
process exits in turn. When the session leader exits, the awk process
becomes a member of an orphaned process group: it has lost its controlling
terminal, its parent is not in the same session, and there's no living
process that can control it (read the Posix standard for the definition of
an orphaned process group).

The kernel cleans up the members of the orphaned process group by sending
them SIGHUP. That's how the awk process gets killed.

This is all fundamental to the Posix process model. It's not appropriate to
spell it all out in the bash manual.
-- 
``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]