Chapter 6

Processes

Introduction

This chapter describes Unix's facilities for running more than one command at once. With the X Window System, the simplest way of running another command is to start a new xterm and do it there. This makes these facilities less useful than they were back in the days when Unix was used via a simple VDU. However, X and Unix only work so well together because Unix was designed to run more than one simultaneous command per user. Also, some of the vi editor's most powerful features depend on this.

Often more than one process

The execution of a command is known as a process. All multi-user operating systems have to run more than one process at once but Unix was the first to let each user have more than one process. We call this: user multi-processing. In fact, we have already seen Unix running more than process; that's what happens when we execute a pipeline. Something remarkable about this:

$ ls | tee tout | wc -l
$

is that Unix automatically synchronises the execution of the three processes so that each stage only produces output when the next is ready to consume it.

No need to wait

Being able to multi-process can save us much waiting. Suppose we wish to sort a huge file, we might type this:

$ sort -o gigantic gigantic
<----- a long delay
$

We would have to wait while sort finished before we could give our next command. If we add an ampersand (&) to the end of the command, Unix does not wait for the sort process to finish before it gives us a prompt:

$ sort -o gigantic gigantic &
26970
$

The number is the unique process identity (PID) of the new process. If we don't dawdle, we can see what processes we have running:

$ ps
   PID TTY      TIME CMD
 26970 pts/45   0:01 sort
 26914 pts/45   0:00 sh
$

Surprisingly, ps does not show itself. It does however, show sort and the shell. (The sh is Unix's name for the Bourne shell.) Later, ps shows that the sorting is over:

$ ps
   PID TTY      TIME CMD
 26914 pts/45   0:00 sh
$

TTY indicates the input/output connection between the xterm and Unix. No xterm process appears in the list because, by default, ps only shows processes associated with a terminal.

Stopping a process

The PID can be used to stop a process:

$ kill 26970
$ kill -9 26970
$

The second form of the command gets rid of stubborn processes.

New windows and &

Commands such as xman and xedit start a new window. If we issue the command without an ampersand, we can't use the old window until the new one disappears. That is why we should use this form of command:

$ xman &
26991
$ xedit file &
26993
$

for programs that run in their own windows.

Run processes later - at

Unix has several commands for running other commands later, at is one of them:

$ at -m 0730 tomorrow
sort -o gigantic gigantic
^D
$

Notice how the command at will execute is read from standard input.

Leaving processes running - nohup

When an xterm stops, the processes it started are stopped automatically. The following command lets users leave processes running after the xterm stops:

$ nohup xman &
26997
$ Sending output to nohup.out

Processes can even be left running after we log off:

$ nohup sort -o gigantic gigantic &
27001
$ Sending output to nohup.out

Unfortunately nohup's output obscures shell's prompt.

A stack of shell processes

This next section is very complicated; we tackle it now because it will help us to understand Unix's means of executing shell scripts when we cover them in Chapter ??.

Unix lets us start extra shells in the same window. Now that we know the name of the Bourne shell, we can easily do so. To clarify what follows, we will make a set of directories to play with:

$ mkdir level1 level1/level2 level1/level2/level3
$

We then start a new shell process and change to another directory:

$ sh
$ cd level1
$

We do that twice more and display our current directory and list of processes:

$ sh
$ cd level2
$ sh
$ cd level3
$ pwd
/homedir/cms/ps/book.unix/level1/level2/level3
$ ps
   PID TTY      TIME CMD
 26914 pts/45   0:00 sh
 27009 pts/45   0:00 sh
 27010 pts/45   0:00 sh
 27015 pts/45   0:00 sh
$

Process 26914 is the original shell in the original directory and is waiting for process 27009 to finish. Process 27009 is in level1 waiting for 27010 which is in level2 waiting for 27015. Process 27015 is the last shell that prompted us; it is in level3.

If we now stop the three extra processes we will be back where we started. On the way we can confirm that the waiting shells were in the predicted directories:

$ ^D
$ pwd
/homedir/cms/ps/book.unix/level1/level2
$ ^D
$ pwd
/homedir/cms/ps/book.unix/level1
$ ^D
$ pwd
/homedir/cms/ps/book.unix
$ ps
   PID TTY      TIME CMD
 26914 pts/45   0:00 sh
$

When we were in level3, we had a stack of four shell processes running.

Programmers will realise the importance of this: it is the mechanism that allows local variables and recursion in shell scripts. It also explains why shell scripts cannot easily leave the user in another directory!

Escape processes

The power of processes makes it possible for the user of interactive commands, such as mailers and editors, to escape from them temporarily to execute other commands. For example if we were using the vi editor, we could execute the date command like this:

...(vi)
:!date
Thu Mar 20 14:50:23 GMT 1997
[Hit return to continue]
(vi)...

It is vi that asks us to hit the return key after the execution of date. Of course, we can run any command - even the shell:

...(vi)
:!sh
$ cp file1 file1.bu
$ cp file2 file2.bu
$ cp file3 file3.bu
$ ^D
[Hit return to continue]
(vi) ...

Running the shell means we can do lots of commands before returning to the editor.

An even more powerful facility is that vi can take text from the screen, feed it through any Unix command and replace the text on the screen with the output from the command. Here we sort all the lines in the file without leaving vi:

...(vi)
:1,$!sort
(vi)...

Here we format all the text being edited:

...(vi)
:1,$!fmt
(vi)...

We could easily use this facility to put a C program through a pretty-printer.

We can even execute Unix commands that we are editing:

...(vi)
:1,$!sh
(vi)...

without leaving the window!

None of these powerful facilities would be possible without Unix's user multi-processing.

QUESTIONS

  1. pending

  2. pending

ANSWERS

  1. pending

  2. pending