Saturday, October 31, 2009

The Magic of Job Control













The Magic of Job Control


Quite awhile ago (in about 1979), people (actually, our pal Bill) noticed that, many times, you run a program, realize that it will take longer than you thought, and decide that you want to switch it to a background program. At the time, the only choices you had were to wait or to kill the program and start it over by using an & to run it in the background. Job control enables you to change your mind after you start a program.



�Warning��The job-control business requires some cooperation from your shell. In SVR4, all three shells handle job control. In some earlier versions of UNIX, only the C shell, or sometimes the C shell and Korn shell, handled job control.


Suppose that you start a big, slow program by typing this line:



bigslowprogram somefile anotherfile

The program runs in the foreground because you didn’t use an ampersand (&). Then you realize that you have better things to do than wait, so you press Ctrl+Z. The shell responds with the message Stopped. (If it doesn’t, you don’t have a job-control shell. Sorry. Skip the rest of this chapter.) At this point, your program is in limbo. You can do three things to it:




  • Continue it in the foreground as though nothing had happened, by typing fg (which stands for foreground).




  • Stick it in the background by typing bg (for background), which makes the program act as though you started it with an & in the first place.




  • Kill it if you decide that you shouldn’t have run it. This method is slightly more complicated. Details follow.






Take this job and . . .


UNIX calls every background program you start a job. A job can consist of several processes (which, as you know, are running programs). To print a list of all your files in all your directories with titles, for example, you can type this line:



ls -lR | pr -h "My files" | lp &

This command lists the files with ls, adds titles with pr, and sends the mess to the printer with lp, all in the background. Although you use three different programs and three separate processes, UNIX considers it one job because each of the three programs needs the other two in order to get work done.


Every regular command (those you issue without an &) is also a job, although, until you use Ctrl+Z to stop it, that’s not an interesting piece of information. You can use the jobs command to see which jobs are active. Here’s a typical response to the jobs command:


 [1] - Stopped (signal)   elm
[2] + Stopped vi somefile

This listing shows two jobs, both of which have been stopped with Ctrl+Z. One is a copy of elm, the mail-reading program; the other job is the vi editor. (The difference between Stopped (signal) and plain Stopped is interesting only to programmers, so we don’t discuss it much.) One job is considered the current job — the one preceded by a plus sign (+); it’s the one most recently started or stopped. All the rest are regular background jobs, and they can be stopped or running.



. . . stick it in the background


You can tell any stopped job to continue in the background by using the bg command. A plain bg continues the current job (the one marked by a plus sign) in the background. To tell UNIX to continue some other job, you must identify the job. You identify a job by typing a percent sign (%) followed by either the job number reported by jobs or enough of the command to uniquely identify it. In this case, the elm job is called %1, %elm, or %e because no other job uses a command starting with an e. As a special case, %% refers to the current job. Although some other % combinations are available, no one uses them. Typing bg %e, for example, continues the elm job in the background.




. . . run it in a window in the foreground


To put a process in the foreground, where it runs normally and can use the terminal, you use the fg command. Continuing a job in the foreground is so common that you can use a shortcut: You just type the percent sign and the job identifier. Typing %1 or %e, for example, continues the elm job in the foreground. Typing %v or %%, however, continues the vi editor in the foreground.










. . . shove it


To get rid of a stopped or background job, use the kill command with the job identifier or (if it’s easier, for some reason) the PID. You can get rid of the vi editor job by typing this line:



kill %v

Typically, you start a job, realize that it will take longer than you want to wait, press Ctrl+Z to stop it, and then type bg to continue that process in the background.


Alternatively, you interrupt a program by pressing Ctrl+Z, run a second program, and, when the second program is finished, type fg or %% to continue the original program.


You don’t often bring in the gangster kill to turn out the lights on a program, although knowing that you have friends in the underworld who can put a nasty program to sleep for good is nice to know. Chapter 24 talks more about it.







What happens when two programs try to use the terminal?


Suppose that a program running in the background tries to read some input from your terminal. Severe confusion can result (and did, in pre-job-control versions of UNIX) if both the background program and a foreground program — or even worse, two or three background programs — try to read at the same time. Which one gets the stuff you type? Early versions of UNIX did the worst possible thing: A gremlin inside the computer flipped a coin to decide who got each line of input. That was, to put it mildly, not satisfactory.


With the advent of job control, UNIX enforced a new rule: Background jobs can’t read from the terminal. If one tries, it stops, much as though you had pressed Ctrl+Z. Suppose that you try to run the ed editor in the background by using this command:



ed some.file &

UNIX responds:


 [1]   + Stopped (tty input)   ed

As soon as ed started and wanted to see whether you are typing anything it should know about, the job stopped. You can continue ed as a foreground program by typing fg or %% if you want to type something for ed. You can kill it (which is all that ed deserves) by typing kill %%.











Full-screen programs and job control


Programs that take over the entire screen (or the entire terminal window), notably the vi and emacs editors and mail programs such as elm, treat the Ctrl+Z interrupt in a slightly different way. Just stopping the program and starting it again later isn’t adequate; the screen shows the results of what you did in the meantime. To solve this problem, full-screen programs make arrangements with UNIX to be notified when you press Ctrl+Z and again when you continue them so that they can do something appropriate, such as redraw the screen when you continue. This process generally is all automatic and obvious, although people occasionally are confused when the screen is magically returned after they give the fg command.












No comments:

Post a Comment