# Background Jobs: &, jobs, fg and bg

An & at the end of a command runs it in the background and gives you the prompt back; jobs lists what's running, Ctrl+Z pauses the job in front, fg and bg bring a job back or let it carry on behind you, and nohup keeps a job running after the terminal closes.

Journeyman · Unix · Linux · Updated November 10, 2026

## After this lesson you can

- Run a command in the background with &, and move a job with jobs, Ctrl+Z, fg and bg
- Keep a job running after the terminal closes with nohup, its output sent to a log file

## Key takeaways

- An & at the end of a command runs it in the background: bash prints its job number and PID, and the prompt comes straight back. $! holds that PID.
- Send a background job's output into a file, so it doesn't mix with your typing.
- jobs lists this terminal's jobs. fg brings one to the front, Ctrl+Z pauses it, and bg lets a paused job carry on in the background. %1 means job 1.
- A paused job does nothing until you resume it, and bash reminds you about it when you try to exit.
- Closing a terminal sends its jobs the HUP signal, which stops them. nohup COMMAND > log 2>&1 & keeps one running.

You're exporting a vacation video from the terminal, and it'll take ten minutes. Until it's done, the terminal is busy, and you can't type a thing. You could open another tab, but on a server you've logged in to, one terminal may be all you have, and when you close the laptop, the export stops halfway. A web developer starts a development server and keeps working beside it; an administrator starts a long backup on a server and logs off. Both run the program **in the background**, behind their typing.

These examples use `export-video.sh` from the practice folder in *What's Running: ps, top and htop*, a pretend export that writes one line a second for ten minutes. Run them in `~/terminal-practice/processes`.

## Run it in the background: &

An `&` (read "and keep going") at the end of a command starts it in the background and hands the prompt straight back. A background job still prints into your terminal, right in the middle of your typing, so send its output into a file with `>` (*Three Streams: Output, Errors and Input*):

```bash
./export-video.sh > export.log &
```

```text
[1] 3124
```

`[1]` is its **job number** in this terminal, and 3124 is its PID. `$!` (read "the last background PID") remembers that PID, so a script can save it and stop the job later:

```bash
echo $!
```

```text
3124
```

Check how far it's got whenever you like:

```bash
tail -n 1 export.log
```

```text
Exported frame 5 of 600
```

## jobs, fg, Ctrl+Z and bg

`jobs` lists the jobs this terminal started:

```bash
jobs
```

```text
[1]+  Running                    ./export-video.sh > export.log &
```

`fg` (for *foreground*) brings a job back to the front: bash prints its command, and the terminal is busy again. Now press **Ctrl+Z**. It pauses the job in front and gives you the prompt back; bash calls a paused job "Stopped":

```bash
fg
```

```text
./export-video.sh > export.log
^Z
[1]+  Stopped                    ./export-video.sh > export.log
```

Paused really means paused. Ctrl+Z sends the job a signal of its own, **TSTP** (*terminal stop*), and it freezes where it is, keeping its memory and its open files. Look at the log twice, three seconds apart:

```bash
tail -n 1 export.log; sleep 3; tail -n 1 export.log
```

```text
Exported frame 10 of 600
Exported frame 10 of 600
```

`bg` (for *background*) lets a paused job carry on, behind you, as if you'd started it with `&`:

```bash
bg
```

```text
[1]+ ./export-video.sh > export.log &
```

![A job's three states as boxes joined by arrows: In front, where the terminal is busy; Paused, which jobs calls Stopped; and In the background, where the prompt is free. Ctrl+Z leads from In front to Paused, bg from Paused to In the background, and fg from Paused or from In the background back to In front. A command ending in & starts In the background](https://fsdtrainingmedia.blob.core.windows.net/public/images/2026/11/3d409759d91c40d0bd5eac5887e9e376.webp)

Moving jobs between the front and the back like this is called **job control**. With more than one job, name each with `%` and its number: `fg %2`, `bg %1`. `kill` from *Stopping Things: kill and Signals* takes the same names, so you don't need the PID. The `Terminated` line shows the next time bash prints a prompt; press Enter if it doesn't appear:

```bash
kill %1
```

```text
[1]+  Terminated                 ./export-video.sh > export.log
```

## Don't leave a job paused

People press Ctrl+Z by mistake all the time: in most other programs, it means undo. Some people press it to get out of a program, too, and forget that the program is still there, paused and holding its files open. bash reminds you when you try to leave. Start the export in the front, press Ctrl+Z after a second, and type `exit`:

```bash
./export-video.sh > export.log
```

```text
^Z
[1]+  Stopped                    ./export-video.sh > export.log
```

```bash
exit
```

```text
exit
There are stopped jobs.
```

The terminal stays open. `jobs` shows the paused job: finish it with `fg`, or stop it with `kill %1`. Type `exit` a second time in a row and bash closes anyway, stopping the paused job with it.

## Keep it running after you close the terminal: nohup

Closing a terminal "hangs it up", a phrase from the days when terminals were wired to computers over phone lines, and the system sends each of its jobs the **HUP** signal (for *hang up*), which stops them. Try it: open a new terminal tab, start `./export-video.sh > export.log &` there, close that tab, and look from your first terminal. `pgrep` finds nothing, because the export is gone:

```bash
pgrep -af export-video
```

`nohup` (read "no hang up") starts a program that ignores HUP. Put it in front of the command, and send the errors to the log too with `2>&1`:

```bash
nohup ./export-video.sh > export.log 2>&1 &
```

```text
[1] 3534
```

Close that terminal, and look again from another one:

```bash
pgrep -af export-video
```

```text
3534 bash ./export-video.sh
```

Still exporting, and `tail export.log` shows how far. When you're done practicing, stop it with `pkill -f export-video`. Without `>`, `nohup` saves the output in a file called `nohup.out` and says so:

```bash
nohup ./export-video.sh &
```

```text
[1] 3593
nohup: ignoring input and appending output to 'nohup.out'
```

`nohup` suits a one-off job: a long download, a backup, an export. A program that must run all the time, such as a website, is set up as a service instead, which the system starts by itself. On a Mac, zsh has the same commands; it words its job messages a little differently, and it reminds you about running jobs, not only paused ones, when you exit.

## Check yourself

2 questions to try on the lesson page.

## So what

With `&`, `jobs`, `fg`, `bg` and `nohup`, one terminal can run a long job and still be yours to type in, and the job can outlive the terminal that started it.

## Key terms

- [Background Job](https://www.ask-codey.com/glossary/background-job)
- [Job Control](https://www.ask-codey.com/glossary/job-control)
- [nohup](https://www.ask-codey.com/glossary/nohup)

## Cheat sheets

- [Background Jobs: &, jobs, fg and bg](https://www.ask-codey.com/cheat-sheets/bash-background-jobs-cheat-sheet)

## Related

- [What's Running: ps, top and htop](https://www.ask-codey.com/lessons/bash-processes)
- [Stopping Things: kill and Signals](https://www.ask-codey.com/lessons/bash-kill-and-signals)
- [Three Streams: Output, Errors and Input](https://www.ask-codey.com/lessons/bash-streams-and-redirection)

Source: https://www.ask-codey.com/lessons/bash-background-jobs
