Alex
Alex

Reputation: 635

Job aware shell vs job unaware shell execution of programs

As I was reading APUE v3, more specifically, I found myself unable to grasp some things. First of all, let's asume that I run the following piped programs in a UNIX shell:

cat /etc/passwd | grep -i alex | awk -F : '{print $3}' | less

In the first example let's assume that I'm using a job unaware shell (sh)

The book explains that, in this situation, an eventual ps -o pid,ppid,pgid,comm would look like this (assuming the the pid of the shell is 10 and it's ppid is 5)

PID     PPID     PGID     COMM
10       5       10        sh
11       10      10        less
12       11      10        cat /etc/passwd
13       11      10        grep -i alex
14       11      10        awk -F : '{print $3}'

In the second example let's assume we're using a job aware shell (bash):

PID      PPID     PGID     COMM
10       5       10        bash
11       10      11        cat /etc/passwd
12       10      11        grep -i alex
13       10      11        awk -F : '{print $3}'
14       10      11        less

The question is, why in the second case, the processes are the children of the shell, and not of the last process ( as is in the first case), and presuming that shell receives a SIGCHLD for each of it's children, doesn't some kind of race condition occur between the children?

PS. Sorry for the wrong indentation. I'll try and fix it now Thanks, Alex

Upvotes: 2

Views: 65

Answers (1)

Dummy00001
Dummy00001

Reputation: 17430

The question is, why in the second case, the processes are the children of the shell, and not of the last process [...]

Because that is correct behavior. Only a bug in shell can explain why less would be a parent of the other processes in the pipe. The less can't handle the SIGCHLD of the other processes because it hasn't started them. (What's more, that would also cause problems due to syscalls in less failing with EINTR errors.) That would also mean that all the processes except less would be reaped by PID 1, not the shell, since it would receive their SIGCHLD.

Otherwise, the parent-child relation of the processes has nothing do to with the "job aware shell". Job aware shell does two things: it implements the job controls (jobs, fg, bg commands) and it sets itself as a session leader (using the setsid() syscall) so that SIGHUP would be sent automatically to all child processes when it (shell) terminated.

[...] and presuming that shell receives a SIGCHLD for each of it's children, doesn't some kind of race condition occur between the children?

Race condition refers to the situation where things are executed not in the expected order. Here, there is no expected order. Most filter applications (filters like grep: read from stdin, write to stdout) would terminate as soon as they would see EOF on stdin. It happens often that the first processes in the pipe might already terminate by the time the last process has seen any input. And that is normal. They are reaped, but their output has been already sent down the pipe and would be processed normally.

Upvotes: 1

Related Questions