[cs631apue] About login sh process

Jan Schaumann jschauma at stevens.edu
Fri Dec 13 11:03:03 EST 2019


Yuxi Wang <ywang286 at stevens.edu> wrote:

> 1.It seems the login shell will fork a process named ?sh?, and then this ?sh? forks to run the command.

That depends on the system / shell.  The shell can
implement the processing of commands and pipelines
differently: it may choose to fork-exec the process
directly or fork-fork-exec.

Slide 31 of Lecture 07 illustrates the sequence of
direct fork-exec for each process; what you're seeing
is the fork-fork-exec where each command is run in a
separate fork.

Try to run the same command with increasingly longer
pipelines to see whether your shell creates a new
shell for each command or only for the pipeline.  For
example, NetBSD's /bin/sh and /bin/ksh both only
create one extra shell for the entire pipeline:

$ ( ps -o pid,ppid,pgid,sid,comm; sleep 1; ) | ./cat1 | ./cat2 | more | less | cat
 PID PPID PGID SID COMMAND
  80   81   80  80 -sh 
 386   80  386  80 -sh 
 468   80  386  80 ./cat1 
 680   80  386  80 more 
 683  386  386  80 -sh 
 774   80  386  80 less 
1388   80  386  80 ./cat2 
1404   80  386  80 cat 
1470  683  386  80 ps 

The current shell we're initiating the pipeline above
from is PID 80.  That process reads the entire line
entered and:

- forks a new process (PID 386) for the first command of the
  pipeline
  - the first command is a subshell "( ps ...)", so
    PID 386 forks a new shell (PID 683)
  - the subshell (PID 683) forks a process (PID 1470)
    for execution of the ps(1) command
  - the 'sleep' command is a built-in and executes
    within PID 683 after 1470 completes
- forks a new process (PID 468) for the second command (cat1)
- forks a new process (PID 1388) for the third command (cat2)
- forks a new process (PID 680) for the fourth command (more)
- forks a new process (PID 774) for the fifth command (less)
- forks a new process (PID 1404) for the sixth command (cat)


(We use the subshell to add the sleep so that the
ps(1) command will see the actual command names; if
you leave out the subshell and the sleep you will only
see '-sh' processes.)


> 2.The shell process we used to type in the command should be the ?sh? not ?-sh?.

In the example above, all shells are '-sh', because
our initial shell is a login shell.  (A login shell
differs from a regular shell in what startup files it
reads and how it's initial environment is set up;
this is usually done by the login mechanism for you,
but you also generally invoke any shell as a login
shell via a command-line option, commonly '-l'.)

Any fork of a login shell is also a login shell, since
by the semantics of fork(2) the parent and child are
(mostly) identical.

In your example, you appear to be logged in via ssh as
'g_cream'; that user appears to have run e.g. su(8),
but invoked without '-l', leading to a root shell
(PID 811) in which root ran the command 'ps -ajx'.

User 'g_cream' is also logged in on the console (PID
40 via 755), so also gets a login shell there.

-Jan


More information about the cs631apue mailing list