LearnLinux FoundationsJob Control

Job Control Overview

jobs - a hands-on Linux lab on a real virtual machine.

The mental model that opens the Job Control module. One terminal can run more than one job: the foreground job owns your keyboard right now, background jobs run while the shell hands your prompt back, and the shell keeps a per-shell job table with numbered entries and + and - marks. Every job is Running, Stopped, or Done. Meet the controls the module teaches next (&, Ctrl-Z, jobs, fg, bg, nohup) and the two traps that bite beginners: the stopped-jobs warning on exit and losing background jobs when the shell dies.

Everything you have run so far took over your terminal, finished, and gave the prompt back. One command at a time, front and center. That is the tidy picture, and it is about to get bigger.

A single terminal can run more than one thing at once. It can hold one command in front of you while others keep working out of sight, and it can freeze a command mid-run and thaw it later. Managing that traffic has a name: job control. This module is about the small set of controls that do it, and this first lesson gives you the map before you touch a single one.

The black boxes in this lesson are a practice terminal: a safe sandbox that checks the one command each step teaches, so you cannot break anything. Two of the drills touch real shell output. When you start a background job, the shell answers with a small job number in brackets and a longer PID. The PID is handed out fresh by the system every time, so the exact digits shown here are one real capture. Yours will read differently, and that is expected.

Two words carry this whole module, so pin them down now.

The foreground job is the one command that owns the terminal and your keyboard right now. When you type and press Enter, whatever runs takes the foreground: it holds the screen, it reads your keystrokes, and the shell waits for it to finish before handing the prompt back. There is only ever one foreground job at a time.

A background job is one the shell runs while giving you the prompt back. It keeps working out of sight, and you can start more commands, including more background jobs, while it runs. The shell does not wait for it. You can have many background jobs going at once.

Picture a chef at the stove. The pot on the front burner is the one being actively stirred, watched, tasted: that is the foreground, and there is only one at a time. The pots simmering at the back are the background jobs, cooking away while the chef gives full attention to the front. Same cook, same kitchen, several things happening at once.

The shell keeps a private list of the jobs it is running or holding for you. That list is the job table, and each job on it gets a job number in square brackets: the first is [1], the next is [2], and so on. The job number is how you name a job when you want to act on it.

Two facts about that table matter from the start. First, it is per-shell: the table belongs to the one shell that started the jobs. Open a second terminal and it has its own, empty table; it cannot see the jobs from the first. Second, the shell marks two of the entries. A + points at the current job, the one a bare control acts on by default, and a - points at the previous one. Those marks move as jobs come and go.

You can look at this table yourself with a command called jobs. You will meet it properly in its own lesson later; here you just peek. In a fresh shell with nothing running, the table is empty, so jobs prints nothing at all. Before you run it, commit to that picture: an empty table means an empty answer.

jobs

prompt: student@linuxcamp:~$ answer: jobs output: hint: Just the four letters and Enter. With nothing running, it prints nothing: jobs

Nothing printed, and that is the correct answer. jobs lists the shell's job table, and in a brand-new shell that table is empty, so there is simply nothing to show. It is not an error and it is not broken. An empty job table is what a quiet shell looks like. Next you will put something in it.

Every job on the table is in exactly one of three states. Learn these three words and the rest of the module clicks into place.

Running means the job is actively working. It can be running in the foreground, holding your terminal, or running in the background while you keep typing. Either way, it is doing its work.

Stopped means the job is suspended: frozen in place, using no processor time, but not gone. It is paused, and it can be resumed right where it left off. Think of a chef lifting a pot off the heat to deal with something else, then setting it back on the burner later. Nothing is lost; the cooking just pauses.

Done means the job has finished and exited. It has left the table. The shell tells you a background job is done the next time you press Enter, then drops it from the list.

So a job is born Running, may be Stopped and resumed as many times as you like, and eventually ends up Done. Those three words are the whole life story of every job you will ever manage.

Time to fill that empty table. The cleanest way is sleep, a command that does nothing but wait a set number of seconds and then exit. Add an & to the end and the shell starts it in the background and hands your prompt straight back. You will meet the & operator in full in the very next lesson; here you only need to see that it puts a job on the table.

Before you run it, commit to a picture. The shell will answer with one line holding two numbers, a job number in brackets and a PID, then return your prompt with the sleep still counting down out of sight.

sleep 30 &

prompt: student@linuxcamp:~$ answer: sleep 30 & output: [1] 12345 hint: Type the command, a space, then a single ampersand at the very end: sleep 30 &

That line is this machine's, captured once. The [1] will match for you, because it is the first job in a fresh shell, but the 12345 is a PID the system picked this one time. Yours will be a different number. The [1] is the job number, the shell's own counter; the PID is the process ID, the number the whole system uses to name that exact running process. Job number for you, PID for the system.

Now the table is not empty. Run jobs again and this time it has something to show: the one Running job you just started. This is the payoff of the whole lesson, the mental model made visible.

Before you run it, decide what you expect: one line, for the one job, and its state should be the first of the three you just learned.

jobs

prompt: student@linuxcamp:~$ answer: jobs output: [1]+ Running sleep 30 & hint: Same four letters as before. This time the table is not empty: jobs

Read the line left to right and the whole model is in it. The [1] is the job number from the table. The + right after it marks this as the current job, the one a bare control would act on by default. Running is its state, the first of the three you learned. And sleep 30 & is the command itself, printed back so you know which job this is. One row, because there is one job. That single line ties together everything this lesson named: the table, the number, the mark, and the state.

You now have the map. The rest of this module hands you the controls, one lesson each. You have already glimpsed two of them; here is the whole set, so you know what is coming and what each one is for. Do not memorise the commands yet. Just see that each is a move on the table you now understand.

Each of the next lessons is one of these controls. That is the shape of the module: this lesson gave you the board and the pieces, and every lesson after it teaches one move.

Two traps catch almost everyone the first time, and both come straight from the model you just learned. Meeting them now means you will recognise them instead of panicking.

The first is the Stopped job on exit. If you try to close a shell that still has a job in the Stopped state, the shell does not just quietly kill it. It warns you first:

There are stopped jobs.

That message is the shell protecting you. It is saying you have a paused job on the table and closing now would end it. Press the exit again and it will close anyway, taking the stopped job with it, so the warning is your one chance to go rescue that job first.

The bigger trap is quieter: background jobs are tied to the shell that started them. Close that terminal, log out, or drop the connection, and its background jobs usually die with it, no warning at all. The job table lives inside that one shell, so when the shell is gone, so is the table and everything on it. There is one control built to break that link and let a job outlive its shell, called nohup, and it has its own lesson later in this module. For now, just know the risk: a background job is not the same as a job that survives logout.

Scaffolding off. No command is printed this time. You have every piece you need.

You started a job a moment ago and you want to see the shell's list of what it is running or holding for you, the table with the job numbers and states. Ask the shell to show you that list.

prompt: student@linuxcamp:~$ answer: jobs output: [1]+ Running sleep 30 & hint: You want the shell's own list of jobs. The command is named for exactly that thing.

The command is jobs, and it prints the job table. Every job the shell is running or holding shows up there, each with its number in brackets, its + or - mark, its state, and the command that made it. Your job number matches because it is the first job in the shell, and the state reads Running because the sleep is still counting down. You recalled the command from its job alone, which is exactly the recall the real machine will ask of you.

You earned this cheat sheet. It is the model, not a command list, because the model is what makes every command in this module make sense:

Two rules to carry forward. The job table is per-shell: a second terminal shows none of the first one's jobs. And a background job is tied to its shell: close the shell and the job usually dies with it, unless you used nohup.

When a later lesson mentions the current job, or a control that acts without you naming a number, it means the job marked + on the table. That is why the mark matters: it is the shell's answer to the question which job did you mean. Keep the picture of the table in your head and the rest of the module reads like moves in a game whose board you already know.

The practice terminal has shown you the whole model. One terminal can run more than one job, split between the foreground and the background. The shell tracks them in a job table with its numbers and its + and - marks, and every job sits in one of three states. You saw the table empty, filled it with one background job, and read it back. Every command you typed yourself.

From here the module hands you the controls one at a time. The very next lesson is the & operator you just borrowed, then come Ctrl-Z, jobs, fg, bg, and nohup, each one lesson, each one move on the table you now understand. The module ends with one real Linux machine, the Job Control capstone mission. A VM boots just for you, with its own shell and its own job table. There you background jobs, suspend them, list them, and pull them back to the foreground for real. One difference from here: the mission shows no commands. You read the objective, you recall the control, you type it. That recall is what makes it stick.

Start with the next lesson and learn the first control, then work your way to the capstone.

Practice Job Control Overview in a real Linux terminal at The Linux Camp. Progress is verified automatically as you type commands on the machine.