Unix Power ToolsUnix Power ToolsSearch this book

23.3. Using jobs Effectively

So far, you've seen how to get processes into and out of the background. That's a pretty good start, but what happens when you put more than one process in the background? How do you remember what's in the background at all? Fortunately the jobs command, built into Bourne and C shell derviates, lists all your current session's background jobs. Let's see this in action. In the example below, I started several web browsers:

[jjohn@marian jjohn]$ jobs
[1]   Running                 netscape &
[2]-  Stopped                 lynx
[3]+  Stopped                 lynx http://aliensaliensaliens.com

Every background process is assigned a job number by your shell. This number is unique only for your current session. It isn't globally unique like a process ID. In fact, one job number is assigned to processes that are pipelined together. For example, the following line gets only one job number.

$ uniq bigfile.dat | sort | wc -l &

In the jobs example above, the first process was started with an ampersand, so it was immediately backgrounded. Job 2 started as a typical interactive session, but I stopped it with CTRL-z. A stopped process is not the same as a terminated process -- it simply doesn't receive any CPU time. It's like a caveman frozen in ice, waiting to be thawed out and come back to life. If you find that a job is becoming a resource hog, consider using CTRL-z to suspend the process until you figure out why it's being so gluttonous. The next job listed is a new instance of lynx, which is also put into the background so that the jobs command could be run for this listing. The plus sign next to the job number indicates that that job will be in the foreground when fg is typed. That job is known as the current job. The minus sign indicates the previous job, the job that used to be the current job.

Job numbers can be supplied to fg. In the given example, the first version of lynx can be revived using fg %2. You can also kill jobs with the job number. Why have two versions of lynx running? The first one can be terminated with kill %2. You can also supply signal numbers, as you normally would to kill. By default kill sends the TERM (15 on Linux) signal, which will stop most processes.

When a backgrounded job is terminated or completes, you will be notified before the next command prompt is printed. For example:

[jjohn@marian jjohn]$ kill -9 %3
[jjohn@marian jjohn]$
[3]+  Killed                  xcalc
[jjohn@marian jjohn]$

Just as before, the job number is printed with a plus sign, indicating that it was the current job. Because this process exited abnormally (it was sent a KILL signal), the reason is printed next, along with the line that was executed. For a process that runs to completion, the output looks slightly different:

[jjohn@marian jjohn]$ ls | uniq | sort | wc -l &
     99
[2] 10501
[2]+  Done                    ls --color=tty | uniq | sort | wc -l
[jjohn@marian jjohn]$

Here, the command was put in the background immediately. The shell then reported the job number and process ID. Because the command completed very quickly, the shell reports that job 2 exited normally even before the next command prompt could be printed.

As useful as job numbers are, sometimes you don't want to bother running jobs, searching for the desired command, finding its job number, and then running fg %num. Luckily, the job control mechanism uses a simple pattern-matching scheme so that you can supply only part of the command or job you wish to foreground or kill. Instead of prefixing the job number with simply %, use %?. The string you supply must be enough to disambiguate it from all other jobs. Take this job listing, for example:

[1]   Running                 netscape &
[2]   Running                 xcalc &
[3]-  Stopped                 lynx
[4]+  Stopped                 lynx http://aliensaliensaliens.com

I can put the xcalc program in the foreground with fg %?xc, because xc doesn't appear in the other jobs. But I can't refer to either of the lynx processes with any substring of "lynx." If I do, I get something like the following.

[jjohn@marian jjohn]$ fg %?ly
bash: fg: ambigious job spec: ly

Instead, I could refer to the second version with fg %?aliens. In order to get at the first lynx job, its job number must be used explicitly.

You may find that your shell attempts to interpret %? as a filename wildcard. This is increasingly rare, but you may need to escape the ?, so that you can foreground a process. That can be done like this: fg %\?string.

One final shortcut to job control: you can put jobs in the foreground simply by referring to the job number. For instance, typing %2 alone at the command prompt will put job number 2 in the foreground. You can even put jobs into the background with this notation: %2 &. This seems a little terse, even for Unix, but it will save you some typing.

-- JJ



Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.