Job control; refers to the ability to put processes (another word for programs, essentially) in the background and bring them to the foreground again. That is to say, you want to be able to make something run while you go and do other things, but have it be there again when you want to tell it something or stop it. In Unix, the main tool for job control is the shell--it will keep track of jobs for you, if you learn how to speak its language.
The two most important words in that language are fg;, for ``foreground'', and bg;, for ``background''. To find out how they work, use the command ; yes at a prompt.
This will have the startling effect of running a long column of y's down the left hand side of your screen, faster than you can follow. (There are good reasons for this strange command to exist, but we won't go into them now). To get them to stop, you'd normally type ctrl-C to kill it, but instead you should type ctrl-Z this time. It appears to have stopped, but there will be a message before your prompt, looking more or less like this:
It means that the process yes has been ; suspended in the background. You can get it running again by typing ; ; fg at the prompt, which will put it into the foreground again. If you wish, you can do other things first, while it's suspended. Try a few ls's or something before you put it back in the foreground.
Once it's returned to the foreground, the y's will start coming again, as fast as before. You do not need to worry that while you had it suspended it was ``storing up'' more y's to send to the screen: when a program is suspended the whole program doesn't run until you bring it back to life. (And you can type ctrl-C to kill it for good, once you've seen enough).
Let's pick apart that message we got from the shell:
The number in brackets is the ; job number of this job, and will be used when we need to refer to it specifically. (Naturally, since job control is all about running multiple processes, we need some way to tell one from another). The + following it tells us that this is the ``current job'' -- that is, the one most recently moved from the foreground to the background. If you were to type fg, you would put the job with the + in the foreground again. (More on that later, when we discuss running multiple jobs at once). The word Stopped means that the job is ``stopped''. The job isn't dead, but it isn't running right now. Linux has saved it in a special suspended state, ready to jump back into the action should anyone request it. Finally, the yes is the name that was typed on the command line to start the program.
Before we go on, let's kill this job and start it again in a different way. The command is named ; kill and can be used in the following way:
That message about it being ``stopped'' again is misleading. To find out whether it's still alive (that is, either running or frozen in a suspended state), type ; jobs:
There you have it--the job has been ; terminated! (It's possible that the jobs command showed nothing at all, which just means that there are no jobs running in the background. If you just killed a job, and typing jobs shows nothing, then you know the kill was successful. Usually it will tell you the job was ``terminated''.)
Now, start yes running again, like this:
If you read the section about input and output redirection, you know that this is sending the output of yes into the special file /dev/null. /dev/null is a black hole that eats any output sent to it (you can imagine that stream of y's coming out the back of your computer and drilling a hole in the wall, if that makes you happy).
After typing this, you will not get your prompt back, but you will not see that column of y's either. Although output is being sent into /dev/null, the job is still running in the foreground. As usual, you can suspend it by hitting ctrl-Z. Do that now to get the prompt back.
Hmm...is there any way to get it to actually run in the background, while still leaving us the prompt for interactive work? Of course there is, otherwise I wouldn't have asked. The command to do that is ; ; bg:
Now, you'll have to trust me on this one: after you typed bg, yes > /dev/null began to run again, but this time in the background. In fact, if you do things at the prompt, like ls and stuff, you might notice that your machine has been slowed down a little bit (piping a steady stream of single letters out the back of the machine does take some work, after all!) Other than that, however, there are no effects. You can do anything you want at the prompt, and yes will happily continue to sending its output into the black hole.
There are now two different ways you can kill it: with the kill command you just learned, or by putting the job in the foreground again and hitting it with an interrupt (ctrl-C). Let's try the second way, just to understand the relationship between fg and bg a little better;
There, it's gone. Now, start up a few jobs running in simultaneously, like this:
The first thing you might notice about those commands is the trailing & at the end of the first two. ; Putting an & after a command tells the shell to start in running in the background right from the very beginning. (It's just a way to avoid having to start the program, type ctrl-Z, and then type bg.) So, we started those two commands running in the background. The third is suspended and inactive at the moment. You may notice that the machine has become slower now, as the two running ones require significant amounts of CPU time.
Each one told you it's job number. The first two also showed you their ; Process IDentification numbers, or PID's, immediately following the job number. The PID's are normally not something you need to know, but occasionally come in handy.
Let's kill the second one, since I think it's making your machine slow. You could just type kill %2, but that would be too easy. Instead, do this:
As this demonstrates, fg takes parameters beginning with % as well. In fact, you could just have typed this:
This works because the shell automatically interprets a job number as a request to put that job in the foreground. It can tell job numbers from other numbers by the preceding ; %. Now type jobs to see which jobs are left running:
That pretty much says it all. The - means that job number 1 is second in line to be put in the foreground, if you just type fg without giving it any parameters. However, you can get to it by naming it, if you wish:
Having changed to job number 1 and then suspending it has also changed the priorities of all your jobs. You can see this with the jobs command:
Now they are both stopped (because both were suspended with ctrl-Z), and number 1 is next in line to come to the foreground by default. This is because you put it in the foreground manually, and then suspended it. The + always refers to the most recent job that was suspended from the foreground. You can start it running again:
Notice that now it is running, and the other job has moved back up in line and has the +.
Well, enough of that. Kill them all so you can get your machine back:
You should see various messages about termination of jobs - nothing dies quietly, it seems. To summarize what you should know about job control now: