% Linux Installation and Getting Started    -*- TeX -*-
% job-control.tex
% Copyright (c) 1992, 1993 by Matt Welsh, Larry Greenfield and Karl Fogel
%
% This file is freely redistributable, but you must preserve this copyright 
% notice on all copies, and it must be distributed only as part of "Linux 
% Installation and Getting Started". This file's use is covered by
% the copyright for the entire document, in the file "copyright.tex".

\section{Job Control}\label{sec-job-control}

\index{job control|(}
\subsection{Jobs and processes}
\label{sec-process}\label{sec-processes}

\index{shells!job control provided by}
{\bf Job control} is a feature provided by many shells (Bash and Tcsh
included) which allows you to control multiple running commands, or 
{\bf jobs}, at once. Before we can delve much further, we need to talk
about {\bf processes}.

\index{process!defined}
\index{ps@{\tt ps}}
\index{process!ps to list@{\tt ps} to list}
Every time you run a program, you start what is known as a 
{\em process}---which is just a fancy name for a running program.
The command {\tt ps} displays a list
of currently running processes. Here's an example:
\begin{tscreen}
/home/larry\# {\em ps}
\begin{verbatim}
  PID TT STAT  TIME COMMAND 
   24  3 S     0:03 (bash) 
  161  3 R     0:00 ps
\end{verbatim}
/home/larry\#
\end{tscreen}
\index{process!ID!defined}
The {\tt PID} listed in the first column is the {\bf process ID},
a unique number given to every running process. The last column,
{\tt COMMAND}, is the name of the running command. Here, we're only looking
at the processes which Larry is currently running\footnote{There are 
many other processes running on the system as well---``{\tt ps -aux}''
lists them all.}. These are {\tt bash}
(Larry's shell), and the {\tt ps} command itself. As you can see, 
{\tt bash} is running concurrently with the {\tt ps} command.
{\tt bash} executed {\tt ps} when Larry typed the command. After
{\tt ps} is finished running (after the table of processes is displayed),
control is returned to the {\tt bash} process, which displays the
prompt, ready for another command.

\index{job!defined}
A running process is known as a {\em job\/} to the shell. The terms
{\em process\/} and {\em job\/} are interchangeable. However, a process
is usually referred to as a ``job'' when used in conjunction with {\bf
job control}---a feature of the shell which allows you to switch between
several independent jobs.

In most cases users are only running a single job at a time---that
being whatever command they last typed to the shell. However, using job
control, you can run several jobs at once, switching between them as
needed. How might this be useful? Let's say that you're editing
a text file and need to suddenly interrupt your editing and do something
else. With job control, you can temporarily suspend the editor, 
and back at the shell prompt start to work on something else. When you're
done, you can start the editor back up, and be back where you
started, as if you never left the editor. This is just one example. There
are many practical uses for job control.

\subsection{Foreground and background}

\index{process!forground}
\index{process!background}
\index{job!forground}
\index{job!background}
\index{forground process}
\index{background process}
Jobs can either be in the {\bf foreground} or in the {\bf background}.
There can only be one job in the foreground at any one time. The foreground
job is the job which you interact with---it receives input from the keyboard
and sends output to your screen. (Unless, of course, you have redirected
input or output, as described in Section~\ref{sec-plumbing}). On the other
hand, jobs in the background do not receive input from the terminal---in
general, they run along quietly without need for interaction. 

Some jobs take a long time to finish, and don't do anything
interesting while they are running.  Compiling programs is one such
job, as is compressing a large file.  There's no reason why you
should sit around being bored while these jobs complete their tasks;
you can just run them in the background. While the jobs are running
in the background, you are free to run other programs. 

\index{job!suspended}
Jobs may also be {\bf suspended}. A suspended job is a job that 
is not currently running, but is temporarily stopped. After you
suspend a job, you can tell the job to continue, in the foreground
or the background as needed. Resuming a suspended job will not change
the state of the job in any way---the job will continue to run where
it left off.

\index{process!interupting}
\index{job!inturpting}
Note that suspending a job is not equal to {\em interrupting\/}
a job. When you interrupt a running process (by hitting your interrupt
key, which is usually \key{ctrl-C})\footnote{The interrupt key can be
set using the {\tt stty} command. The default on most systems is 
\key{ctrl-C}, but we can't guarantee the same for your system.}, 
it kills the process, for good.
Once the job is killed, there's no hope of resuming it; you'll have
to re-run the command. Also note that some programs trap the interrupt,
so that hitting \key{ctrl-C} won't immediately kill the job. This is to 
allow the program to perform any necessary cleanup operations before exiting.
In fact, some programs simply don't allow you to kill 
them with an interrupt at all.


\subsection{Backgrounding and killing jobs}
Let's begin with a simple example. The command {\tt yes} is a
seemingly useless command which sends an endless stream of {\tt y}'s
to standard output. (This is actually useful. If you piped the output
of {\tt yes} to another command which asked a series of yes and no
questions, the stream of {\tt y}'s would confirm all of the questions.)

Try it out. 
\begin{tscreen}
/home/larry\# {\em yes} \\
y \\
y \\
y \\
y \\
y
\end{tscreen}
\index{process!kill}
\index{process!interupt}
\index{job!kill}
\index{job!interupt}
The {\tt y}'s will continue {\em ad infinitum}. You can kill the process
by hitting your interrupt key, which is usually \key{ctrl-C}. 
So that we don't have to put up with the annoying stream of {\tt y}'s,
let's redirect the standard output of {\tt yes} to {\tt /dev/null}. As
you may remember, {\tt /dev/null} acts as a ``black hole'' for data. 
Any data sent to it will disappear. This is a very effective method of
quieting an otherwise verbose program.
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null}
\end{tscreen}
Ah, much better. Nothing is printed, but the shell prompt doesn't
come back. This is because {\tt yes} is still running, and is sending
those inane {\tt y}'s to {\tt /dev/null}. Again, to kill the job,
hit the interrupt key.

Let's suppose that we wanted the {\tt yes} command to continue to
run, but wanted to get our shell prompt back to work on other things.
We can put {\tt yes} into the background, which will allow it to
run, but without need for interaction.

\index{job!background}
\index{backgrounding jobs}
One way to put a process in the background is to append an ``{\tt \&}''
character to the end of the command. 
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null \&} \\
\verb+[1] 164+ \\
/home/larry\#
\end{tscreen}
As you can see, we have our shell prompt back. But what is this 
``{\tt \verb+[1] 164+}''? And is the {\tt yes} command really running?

The ``{\tt \verb+[1]+}'' represents the {\bf job number} for the {\tt yes}
process. The shell assigns a job number to every running job. Because
{\tt yes} is the one and only job that we're currently running, it
is assigned job number {\tt 1}. The ``{\tt 164}'' is the process ID, or
PID, number given by the system to the job. Either number may be used to
refer to the job, as we'll see later.

\index{jobs@{\tt jobs}}
You now have the {\tt yes} process running in the background, continuously
sending a stream of {\tt y}'s to {\tt /dev/null}. To check on the
status of this process, use the shell internal command {\tt jobs}.
\begin{tscreen}
/home/larry\# {\em jobs} \\
\verb-[1]+  Running                 yes >/dev/null  &- \\
/home/larry\#
\end{tscreen}
Sure enough, there it is. You could also use the {\tt ps} command as 
demonstrated above to check on the status of the job.

\index{kill@{\tt kill}}
\index{process!background!kill}
\index{job!background!kill}
To terminate the job, use the command {\tt kill}.
This command takes either a job number or a process ID number as an
argument. This was job number 1, so using the command
\begin{tscreen}
/home/larry\# {\em kill \%1}
\end{tscreen}
will kill the job. When identifying the job with the job number, you must
prefix the number with a percent (``{\tt \%}'') character.

Now that we've killed the job, we can use {\tt jobs} again to check on it:
\begin{tscreen}
/home/larry\# {\em jobs}
\begin{verbatim}
[1]+  Terminated              yes >/dev/null 
\end{verbatim}
/home/larry\# 
\end{tscreen}
The job is in fact dead, and if we use the {\tt jobs} command again
nothing should be printed.

You can also kill the job using the process ID (PID) number, which is
printed along with the job ID when you start the job. In our example,
the process ID is 164, so the command
\begin{tscreen}
/home/larry\# {\em kill 164}
\end{tscreen}
is equivalent to
\begin{tscreen}
/home/larry\# {\em kill \%1}
\end{tscreen}
You don't need to use the ``{\tt \%}'' when referring to a job by its
process ID.

\subsection{Stopping and restarting jobs}
\index{job!stopping}
There is another way to put a job into the background. You can
start the job normally (in the foreground), {\bf stop} the job,
and then restart it in the background. 

First, start the {\tt yes} process in the foreground, as you
normally would:
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null}
\end{tscreen}
Again, because {\tt yes} is running in the foreground, you shouldn't get
your shell prompt back. 

Now, instead of interrupting the job with \key{ctrl-C}, we'll {\em suspend}
the job. Suspending a job doesn't kill it: it only temporarily stops the
job until you restart it. To do this, you hit the suspend key, which
is usually \key{ctrl-Z}. 
\begin{tscreen}
/home/larry\# {\em yes $>$ /dev/null} \\
\key{ctrl-Z} \\
\verb-[1]+  Stopped                 yes >/dev/null- \\
/home/larry\#
\end{tscreen}
While the job is suspended, it's simply not running. No CPU time is
used for the job. However, you can 
restart the job, which will cause the job to run again as if nothing ever 
happened. It will continue to run where it left off.

\index{fg@{\tt fg}}
\index{job!restarting}
To restart the job in the foreground, use the command
{\tt fg} (for ``foreground''). 
\begin{tscreen}
/home/larry\# {\em fg} \\
yes >/dev/null 
\end{tscreen}
\index{job!background}
\index{bg@{\tt bg}}
The shell prints the name of the command again so you're aware of which job
you just put into the foreground. Stop the job again, with \key{ctrl-Z}.
This time, use the command {\tt bg} to put the job into the background.
This will cause the command to run just as if you started the command
with ``{\tt \&}'' as in the last section.
\begin{tscreen}
/home/larry\# {\tt bg} \\
\verb-[1]+- yes >/dev/null  \& \\
/home/larry\# 
\end{tscreen}
And we have our prompt back. {\tt jobs} should report that {\tt yes}
is indeed running, and we can kill the job with {\tt kill} as we
did before.

How can we stop the job again? Using \key{ctrl-Z} won't work, because
the job is in the background. The answer is to put the job in the
foreground, with {\tt fg}, and then stop it. As it turns out you can use
{\tt fg} on either stopped jobs or jobs in the background.

There is a big difference between a job in the background and a job
which is stopped. A stopped job is not running---it's not using any
CPU time, and it's not doing any work (the job still occupies
system memory, although it may be swapped out to disk). A job in the 
background is running, and using memory, as well as completing some task 
while you
do other work. However, a job in the background may try to display text on
to your terminal, which can be annoying if you're trying to work on
something else. For example, if you used the command
\begin{tscreen}
/home/larry\# {\em yes \&}
\end{tscreen}
without redirecting stdout to {\tt /dev/null}, a stream of {\tt y}'s
would be printed to your screen, without any way of interrupting it (you
can't use \key{ctrl-C} to interrupt jobs in the background).
In order to stop the endless {\tt y}'s, you'd have to use the {\tt fg}
command, to bring the job to the foreground, and then use \key{ctrl-C} 
to kill it.

Another note. The {\tt fg} and {\tt bg} commands normally foreground
or background the job which was last stopped (indicated by a 
``{\tt +}'' next to the job number when you use the command {\tt jobs}).
If you are running multiple jobs at once, you can foreground or
background a specific job by giving the job ID as
an argument to {\tt fg} or {\tt bg}, as in
\begin{tscreen}
/home/larry\# {\em fg \%2}
\end{tscreen}
(to foreground job number 2), or
\begin{tscreen}
/home/larry\# {\em bg \%3}
\end{tscreen}
(to background job number 3). You can't use process ID numbers with
{\tt fg} or {\tt bg}. 

Furthermore, using the job number alone, as in
\begin{tscreen}
/home/larry\# {\em \%2}
\end{tscreen}
is equivalent to
\begin{tscreen}
/home/larry\# {\em fg \%2}
\end{tscreen}

Just remember that using job control is a feature of the shell. The
commands {\tt fg}, {\tt bg} and {\tt jobs} are internal to the shell.
If for some reason you use a shell which does not support job control,
don't expect to find these commands available. 

In addition, there are some aspects of job control which differ between
Bash and Tcsh. In fact, some shells don't provide job control at 
all---however, most shells available for Linux support job control.

\index{job control|)}
