LearnLinux FoundationsJob Control

fg

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

Pull a background or stopped job back to the front with fg. Bare fg for the newest job, %1 to name a job by number, %+ and %- for the current and previous job, and %sleep to name one by its command. Job control values vary: your process ids differ, so the drills lean on the stable job number and mark PIDs illustrative.

In the last few lessons you learned to push work into the background so your terminal stays free. You typed a command, added an &, and got your prompt back while the job ran out of sight. Or you had a command running, pressed a key, and it froze in place so you could do something else.

Now the opposite problem. That job is still there, running or paused, but it is not connected to your keyboard any more. You want it BACK: front and centre, owning the screen, so you can watch it, talk to it, or stop it with a keystroke. There is one command whose entire job is to pull a job back to the front, and it is called fg.

The black boxes below are a practice terminal: a safe sandbox that checks the one command each step teaches, so you cannot break anything. One honest catch for this lesson: when you background a job the shell prints a process id (a number the system assigns, like 12345) that is different every single time and on every machine. So read those numbers as examples. What you TYPE (fg, fg %1) is exactly the same everywhere, and that is what the sandbox grades.

fg is short for foreground. The foreground is simply the job that owns your terminal right now: the one your keystrokes go to, the one whose output you see. fg takes a job that is in the background (or paused) and makes it the foreground job again, reconnecting it to your screen and keyboard.

It is the mirror image of the & and Ctrl-Z you already met. & and Ctrl-Z send a job AWAY from the front. fg brings one BACK. Between them you can move any job in and out of your terminal at will, like moving one window to the top of a stack.

Every job you background gets a small job number in square brackets, [1], [2], and so on, counting up in the order you send them away. That number is how you name a job to fg. Unlike the process id, the job number is predictable: the first job you background is always [1].

Start with the simplest case. You send a single long-running command to the background with &. Here that command is sleep 100, which just does nothing for 100 seconds, a perfect stand-in for real work. The shell answers with a job number and a process id, then hands your prompt straight back:

sleep 100 &

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

The [1] is the job number: this is your first backgrounded job. The 12345 next to it is the process id, and THAT is the part that will read differently for you every time. Do not memorise it. The job number [1] is the handle you will actually use.

Now the star of the lesson. With that one job sitting in the background, type fg all by itself. With no job named, fg grabs the most recent job, the one you last backgrounded or paused, and pulls it to the front. It echoes the command line it is now running so you know exactly what came back:

fg

prompt: student@linuxcamp:~$ answer: fg output: sleep 100 hint: Just the two letters and Enter, nothing after them: fg

That single echoed line, sleep 100, is fg confirming the job is back in the foreground. It is no longer off doing its own thing; it now owns your terminal. Your prompt does not return, because the job is running in front of you and holding the screen, exactly as if you had typed sleep 100 with no &. From here Ctrl-Z would pause it again and Ctrl-C would kill it, because those keystrokes act on whatever job is in the foreground, and right now that is this one.

Bare fg is fine when there is one obvious job. But the moment you have several backgrounded jobs, you need to say WHICH one. You name a job by its number with a percent sign in front: %1 means job 1, %2 means job 2. This is called a job spec.

Picture two jobs already in the background, [1] and [2]. To reach past the most recent one and pull job 1 specifically to the front, you write fg %1. As always, fg echoes the command it brought back:

fg %1

prompt: student@linuxcamp:~$ answer: fg %1 output: sleep 100 hint: fg, a space, then a percent sign and the job number: fg %1

The % is the important character. fg 1 (no percent) is NOT the same thing and will usually error; the shell wants the % to know you mean a job. Read %1 out loud as "job one". The echoed command line here is illustrative; on your machine it will be whatever command you actually put in job 1.

The shell always tracks two special jobs for you: the current job and the previous one. The current job is the most recent, the same one bare fg grabs. In a jobs listing it is marked with a +. The one just before it is marked with a -.

You can name those two directly. fg %+ means the current job (identical to bare fg), and fg %- means the previous job. This saves you looking up a number when you just want "the last one" or "the one before that":

fg %-

prompt: student@linuxcamp:~$ answer: fg %- output: sleep 100 hint: fg, a space, then percent and a minus for the previous job: fg %-

Read the marks in a jobs listing like a map: + is where bare fg will go, - is the runner-up. fg %+ and bare fg do the exact same thing; %+ is just the spelled-out version of the default.

Remembering numbers is a chore. There is a friendlier way: name a job by the START of its command. fg %sleep means "the job whose command begins with the letters sleep". The % still marks a job spec; what follows is a name prefix instead of a number.

This is the form real engineers reach for when they have a job they can recognise by name, a build, an editor, a server, without hunting for its number:

fg %sleep

prompt: student@linuxcamp:~$ answer: fg %sleep output: sleep 100 hint: fg, space, percent, then the first letters of the command: fg %sleep

fg %sleep found the backgrounded job whose command line starts with sleep and pulled it to the front, no number needed. One caution worth carrying: if TWO jobs both start with sleep, the shell cannot tell which you mean and complains about an ambiguous job spec. When names might clash, fall back to the number with fg %1. Prefix-by-name is the fast path; the number is the sure path.

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

You backgrounded two jobs a moment ago. Bare fg would grab the newest one, job 2, but that is not the one you want. You need job number 1 brought back to the foreground, named directly so there is no doubt which job you mean.

prompt: student@linuxcamp:~$ answer: fg %1 output: sleep 100 hint: Name the job by its number. Think fg, then a percent sign, then the number 1.

That is the everyday move. Bare fg always takes the newest job, so to reach a different one you name it with a job spec: the % tells the shell you mean a job, and the 1 picks job number 1. The echoed command line is fg confirming which job came back. You recalled the %n form from memory, which is the same recall the real machine will ask of you.

fg brings a job to the front. The keystroke that does the reverse, freezing a running foreground job, is Ctrl-Z (hold Ctrl, press Z). It is not a command you type at the prompt; it is a signal you send to whatever job is running in front of you. The job stops in place, and the shell prints a line like this:

[1]+ Stopped sleep 100

That Stopped line is what the SHELL prints back to you after you press Ctrl-Z; you do not type it. It reads left to right as: job number [1], the + mark saying this is now the current job, the word Stopped, and the command that was paused. A stopped job is not gone, it is frozen, and fg (or fg %1) is exactly how you wake it back up and return it to the foreground. Ctrl-Z has its own full lesson; here it matters only as the thing fg undoes.

Three fg errors are worth knowing on sight, because each points at a different mistake.

fg: no current job. You ran fg with nothing backgrounded or paused at all. There is simply no job to bring forward. What to check first: run jobs to list what, if anything, is running in the background. An empty list means there is nothing to foreground.

fg: %3: no such job. You named a job number that does not exist, here %3 when there is no job 3. What to check first: run jobs and read the real numbers in the brackets. You may have meant %1.

fg: current: no such job. A variant of the first: the shell went looking for the current job and found none. Same cause, nothing is backgrounded. What to check first: again, jobs. If it prints nothing, start a job before you try to foreground one.

Almost every fg error comes down to one habit: check jobs first. That listing is the source of truth for which job numbers exist and which one carries the +. Name a job that is not on that list and fg has nothing to grab.

You earned this cheat sheet. Every row is a form of fg you just ran:

And the two ideas that tie it together: a job number in brackets ([1]) names a job, and a job spec (%1, %+, %-, %sleep) is how you hand that name to fg. When in doubt about which number is which, jobs shows you the list and the + marks the default.

That same job spec works with more than fg. kill %1 sends a job to be terminated by its job number instead of its process id, so you never have to look the PID up. Once you know the %n shorthand, it follows you across the whole job-control toolkit.

The practice terminal has shown you the shape of fg: bare fg for the newest job, %1 to name a job by number, %+ and %- for the current and previous job, and %sleep to name one by its command. You saw the Stopped line Ctrl-Z prints, and the three errors that all trace back to checking jobs first. Every command you typed yourself, and one you recalled from memory alone.

The Job Control module ends with one real Linux machine, the Job Control capstone mission, and that is where you run fg for real, on jobs you background and pause yourself. A VM boots just for you, with its own live shell. It hands you objectives that use exactly what you practiced across this module: sending jobs to the background, listing them, pausing them, and pulling them back to the front. One difference from here: the mission shows no commands. You read the objective, you recall the command, you type it. That recall is what makes it stick.

Finish the other Job Control lessons, then go move real jobs in and out of a real terminal.

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