Why should you care about process IDs or job numbers? Actually, you could probably get along fine through your UNIX life without ever referring to process IDs (unless you use a windowing workstation-as we'll see soon). Job numbers are more important, however: you can use them with the shell commands for job control. 
 NOTE: If you have an older version of UNIX, it is possible that your system does not support job control. This is particularly true for many systems derived from Xenix, System III, or early versions of System V. On such systems, the Korn shell does not have the fg and bg commands, you can't type [CTRL-Z] to suspend a job, and the TSTP signal doesn't exist. The shell does, however, support everything else discussed here, including job numbers and the jobs and kill commands, if monitor mode is on. To ensure this, put the line set -o monitor in your .profile file.
You already know the most obvious way of controlling a job: you can create one in the background with &. Once a job is running in the background, you can let it run to completion, bring it into the foreground, or send it a message called a signal.
The built-in command fg brings a background job into the foreground. Normally this means that the job will have control of your terminal or window and therefore will be able to accept your input. In other words, the job will begin to act as if you typed its command without the &.
If you have only one background job running, you can use fg without arguments, and the shell will bring that job into the foreground. But if you have several running in the background, the shell will pick the one that you put into the background most recently. If you want some other job put into the foreground, you need to use the job's command name, preceded by a percent sign (%), or you can use its job number, also preceded by %, or its process ID without a percent sign. If you don't remember which jobs are running, you can use the command jobs to list them.
A few examples should make this clearer. Let's say you created three background jobs as above. Then if you type jobs, you will see this:
 Running fred &  - Running bob &  + Running dave &
 2349 Running fred &  - 2367 Running bob &  + 2382 Running dave &
2349 2367 2382
This could be useful with command substitution; see Task 8-1 below. Finally, the -n option lists only those jobs whose status has changed since the shell last reported it - whether with a jobs command or otherwise.
You can also refer to the job most recently put in the background by %+. Similarly, %i- refers to the background job invoked next-most-recently (bob in this case). That explains the plus and minus signs in the above: the plus sign shows the most recently invoked job; the minus sign shows the next-most-recently invoked job. 
 This is analogous to ~+ and ~- as references to the currently and previous directory; see the footnote in Chapter 7, Input/Output and Command-line Processing. Also: %% is a synonym for %+.
If more than one background job has the same command, then
%command will disambiguate by choosing the most recently
job (as you'd expect). If this isn't what you want, you need to use
the job number instead of the command name.
However, if the commands
have different arguments, you can use %
instead of %command. %
?string refers to the
job whose command contains the string.
For example, assume you
started these background jobs:
$ bob pete &  189 $ bob ralph &  190 $
Then you can use %
?ralph to refer to each of
them, although actually %
?pe and %
?ra are sufficient to
Table 8.1 lists all of the ways to refer to background jobs. We have found that, given how infrequently people use job control commands, job numbers or command names are sufficient, and the other ways are superfluous.
|%N||Job number N|
|%string||Job whose command begins with string|
|%?string||Job whose command contains string|
|%+||Most recently invoked background job|
|%%||Same as above|
|%-||Second-most recently invoked background job|
Just as you can put background jobs into the foreground with fg, you can also put a foreground job into the background. This involves suspending a job, so that the shell regains control of your terminal.
To suspend a job, type [CTRL-Z]  while it is running. This is analogous to typing [CTRL-C] (or whatever your interrupt key is), except that you can resume the job after you have stopped it. When you type [CTRL-Z], the shell responds with a message like this:
 + Stopped
To resume a suspended job so that it continues to run in the foreground, just type fg. If, for some reason, you put other jobs in the background after you typed [CTRL-Z], use fg with a job name or number. For example:
fred is running... CTRL-Z  + Stopped fred $ bob &  bob & $ fg %fred fred resumes in the foreground...
The ability to suspend jobs and resume them in the foreground comes in very handy when you have a conventional terminal (as opposed to a windowing workstation) and you are using a text editor like vi on a file that needs to be processed. For example, if you are editing a file for the troff text processor, you can do the following:
$ vi myfile edit the file... CTRL-Z Stopped  vi $ troff myfile troff reports an error $ fg vi comes back up in the same place in your file
Programmers often use the same technique when debugging source code.
You will probably also find it useful to suspend a job and resume it in the background instead of the foreground. You may start a command in the foreground (i.e., normally) and find that it takes much longer than you expected-for example, a grep, sort, or database query. You need the command to finish, but you would also like control of your terminal back so that you can do other work. If you type [CTRL-Z] followed by bg, you will move the job to the background.