Bash — The fg Built-in

Learn how Bash’s fg built-in brings background and suspended jobs back to the foreground. Discover how to use fg, bg, and jobs, understand job numbers, and manage running commands without restarting them.

Bash — The fg Built-in

Imagine that you're working in a terminal. You start a long-running command, send it to the background, and continue doing something else. A few minutes later, you realize that you need to interact with that command again.

Do you need to stop it and start over? Of course not. Bash has a built-in command for exactly this situation: fg.

The fg command brings a background job to the foreground. It can also resume a job that you previously suspended. In other words, it lets you return to a command and give it control of your terminal again.

Let's see how it works, using a few practical examples.

What Does fg Do?

The name fg stands for foreground.

When you run a command in a terminal, it normally runs in the foreground. The shell waits for the command to finish before showing you another prompt. While the command is running, it usually receives keyboard input from your terminal.

For example:

sleep 60

This command waits for 60 seconds. Until it finishes, you won't get your shell prompt back.

You can also run a command in the background by adding & at the end:

sleep 60 &

Now Bash starts the command as a background job and returns the prompt immediately. You can continue using the terminal while the command runs.

But what if you want to bring that job back to the foreground?

That's where fg comes in.

fg

This brings the current job to the foreground, if Bash has a suitable current job.

You can also specify exactly which job you want to bring forward:

fg %1

Here, %1 identifies job number 1 in the current shell.

One important detail: fg works with job specifications, not process IDs. A job number and a process ID are different things, even when they happen to be represented by similar numbers.

Let's Try It with yes

For this example, we'll use the yes command, a classic Unix utility that repeatedly prints a string. By default, it prints the letter y over and over until you stop it.

Try running:

yes

Your terminal will quickly fill with lines of y. Congratulations! You've created a highly productive machine for generating the letter Y.

Press Ctrl+C to stop it.

Now let's run the same command in the background, redirecting its output so it doesn't flood our terminal:

yes &> /dev/null &

Let's break that command down:

  • yes starts the command.
  • &> /dev/null redirects both standard output and standard error to /dev/null, discarding the output.
  • The final & tells Bash to run the command as a background job.

The distinction between the two uses of & matters. The first is part of the redirection syntax &>, while the final one puts the command in the background.

Bash should return a job notification similar to this:

[1] 12345

The exact numbers will vary. Here, 1 is the job number and 12345 is an example process ID.

The command is now running in the background, quietly generating an endless stream of discarded output.

To bring it back to the foreground, run:

fg %1

Bash brings job 1 to the foreground. Because we redirected the output, you won't see the stream of y characters, but your terminal prompt will remain unavailable while the job runs.

To stop the command, press:

Ctrl+C

And just like that, the job is terminated.

Important: Don't run yes without redirecting its output if you plan to leave it running in the background while continuing to use the same terminal. Its output can interfere with your terminal session.

How Do You Know Which Job to Bring Forward?

In the previous example, we used fg %1. But how do you know which job number to use when several commands are running?

Bash provides another useful built-in: jobs.

Start a couple of background commands:

sleep 300 &
sleep 600 &

Bash will assign each job a job number. You can list the jobs with:

jobs

Example output:

[1]-  Running    sleep 300 &
[2]+  Running    sleep 600 &

The numbers in square brackets identify the jobs. The + and - symbols indicate Bash's current and previous jobs, respectively.

Your actual output may differ depending on what you have run in the shell.

To bring the first job to the foreground:

fg %1

To bring the second job to the foreground:

fg %2

If you bring sleep 300 to the foreground, the terminal will wait for that command to finish. Since it sleeps for five minutes, you probably won't want to wait that long just to test the example.

Press Ctrl+C to terminate it, or use Ctrl+Z if you want to suspend it instead.

Do You Always Need to Specify a Job Number?

No. If you run fg without an argument, Bash uses the current job.

For example:

sleep 300 &
sleep 600 &
fg

In this example, fg normally brings the current job—the most recently started job that qualifies as the current job—to the foreground. Here, that will usually be sleep 600.

You can also explicitly refer to the current job using:

fg %%

Bash accepts several job specifications:

Job specificationMeaning
%1Job number 1
%%The current job
%+The current job
%-The previous job
%sleepA job whose command begins with sleep, if the match is unambiguous
%?sleepA job whose command line contains sleep, if the match is unambiguous

The last two forms are useful when you have multiple jobs and want to identify one by its command rather than its number. If the pattern matches more than one job, Bash may report an ambiguity instead of guessing.

For most everyday situations, %1, %2, and the default fg behavior are all you need.

Bringing a Suspended Job Back to Life

So far, we've looked at commands that were started directly in the background. But fg can do something else: resume a job that you've suspended.

Suppose you run a command in the foreground:

sleep 300

While it's running, press Ctrl+Z.

Bash suspends the foreground job and returns the prompt. You should see a message similar to:

[1]+  Stopped    sleep 300

The command hasn't finished. It has simply been suspended.

You now have two choices:

  • Run bg to resume the job in the background.
  • Run fg to resume the job in the foreground.

For example:

fg %1

The command resumes, and the terminal waits for it again.

This is particularly useful when you accidentally start a command in the foreground but want to move it out of the way temporarily.

Here's the usual workflow:

  1. Start a command in the foreground.
  2. Press Ctrl+Z to suspend it.
  3. Run bg to resume it in the background, or fg to resume it in the foreground.
  4. Use jobs to inspect the jobs managed by the current shell.

Remember that Ctrl+Z suspends a job; it doesn't terminate it. If you want to stop a foreground command, Ctrl+C is usually the more appropriate choice.

fg vs. bg vs. &

These three are closely related, but they serve different purposes.

Command or syntaxWhat it does
command &Starts a command in the background
bg %1Resumes a suspended job in the background
fg %1Brings a job to the foreground, resuming it if necessary
jobsLists the jobs managed by the current shell
Ctrl+ZSuspends the current foreground job
Ctrl+CTypically terminates the foreground command

For example, if you want to start a long-running task without waiting for it:

long_running_command &

If you already started a command and suspended it with Ctrl+Z, you can let it continue in the background:

bg

And if you need to interact with that job again:

fg

There is no need to restart the command just to change how it runs relative to your terminal.

What Happens When You Bring a Job to the Foreground?

When Bash brings a job to the foreground, it gives that job control of the terminal. This is important for interactive programs that read keyboard input or respond to terminal signals.

For example, imagine that you've started a text editor in the background:

nano myfile.txt &

Depending on the environment and how the program is launched, an interactive program that attempts to read from the terminal while running in the background may be stopped by the operating system's job-control mechanisms.

You can bring it to the foreground with:

fg

Once it has the terminal, you can interact with it normally.

This is one reason foreground and background execution are more than simply a question of whether a command prints output. Terminal access and job control matter, too.

For commands that are designed to run unattended, such as a long-running calculation or a background download, running in the background is often convenient. For interactive tools, the foreground is generally the natural place to work.

Common Mistakes

Confusing Job Numbers with Process IDs

Suppose jobs -l displays:

[1] 12345 Running    sleep 300 &

Here, 1 is the job number and 12345 is the process ID.

Use the job number with fg:

fg %1

Don't assume that fg 12345 means the same thing. fg expects a job specification, not a process ID.

Trying to Bring a Job Forward from a Different Terminal

Bash maintains its job table for each shell session. If you start a command in one terminal and open another terminal, the second shell generally won't be able to bring the first shell's job forward with fg.

Run jobs in the same shell where you started or suspended the command.

Expecting fg to Restart a Finished Command

If a job has already completed, there is nothing to bring back to the foreground. fg doesn't rerun a command; it changes the foreground/background state of an existing job and resumes it if it's stopped.

Expecting a Background Job to Survive Every Terminal Closure

Job control is designed to manage tasks within a shell session. Simply putting a command in the background doesn't guarantee that it will survive closing the terminal or logging out.

For long-running tasks that must survive disconnection, consider tools such as tmux, screen, nohup, or a proper service manager, depending on your needs.

A Quick Reference

Here are the commands worth remembering:

jobs           # List jobs in the current shell
fg             # Bring the current job to the foreground
fg %1          # Bring job 1 to the foreground
fg %2          # Bring job 2 to the foreground
bg             # Resume the current suspended job in the background
bg %1          # Resume job 1 in the background

You can find more information directly in Bash:

help fg
help bg
help jobs

These commands are Bash built-ins, so you don't need to install any additional utilities to use them.

Conclusion

The fg command is a small but useful part of Bash's job-control toolkit. It lets you return a background job to the foreground or resume a suspended job when you need to interact with it again.

Together, fg, bg, jobs, Ctrl+Z, and Ctrl+C give you practical control over commands running in your terminal. Once you understand the difference between a job number and a process ID—and remember that job control belongs to the current shell—managing foreground and background tasks becomes much less mysterious.

And the next time you send a command into the background, you won't have to wonder how to get it back. Just type fgand bring it home.

Read next

Bash — The bg Built-in

Learn how Bash’s bg built-in lets you resume stopped jobs in the background without interrupting your terminal session. Discover how to use Ctrl+Z, bg, and jobs, understand job specifications, and learn when to use bg instead of fg or &.

Bash — The dirs Built-in

A concise excerpt for the `dirs` post: > Learn how Bash’s `dirs` built-in lets you inspect and manage the directory stack. Explore `-p`, `-l`, `-v`, and `-c`, select specific entries, combine options, and see how `dirs` works together with `pushd` and `popd`.

Bash — The do Keyword

Here’s a short excerpt for the post: > Learn how Bash uses the `do` keyword to mark the beginning of a loop body. Explore how `do` works with `for`, `while`, and `until`, how it pairs with `done`, and how to write clean, readable Bash loops.