Table of Contents
Understanding Foreground and Background Jobs
Working with processes in a shell is not only about starting or killing them. It is also about how they interact with your terminal. The concepts of foreground and background jobs describe how commands use your terminal while they run, and how you can reclaim control of your shell without stopping long running tasks.
What foreground and background really mean
In an interactive shell, a foreground job is the command that currently has control of the terminal. It can read from your keyboard and write directly to the screen. While a foreground job runs, your shell waits for it to finish before returning a prompt.
A background job is a process that your shell started but does not wait for. The shell immediately gives you back a prompt so you can type new commands. Background jobs still run, and they can still write output to the terminal unless you redirect it, but they do not read directly from your keyboard in the normal way.
The shell keeps an internal list of such jobs. This is called job control, and it works only in interactive shells, not in noninteractive scripts.
A foreground job owns your terminal input.
A background job runs while your shell prompt is already available.
Starting a job in the background
You can start most commands directly in the background by placing & at the end of the command line:
sleep 60 &
This tells the shell to start sleep 60 and immediately return a prompt. The shell usually prints a job number in square brackets and the process ID.
If you want to avoid a background job being automatically stopped when it tries to read from the terminal, you should not run interactive programs in the background in a naive way. Background is best suited to commands that do not expect keyboard input, for example long computations, backups, or downloads.
Input and output redirection is often combined with background jobs so their output does not clutter your terminal.
Listing and identifying jobs
The shell keeps track of jobs that are running in the background or have been stopped. You can see them with the jobs builtin:
jobs
The output shows a job number, its state such as Running or Stopped, and the command line. Job numbers are written as %1, %2, and so on when you refer to them.
The jobs list is different from general process listing tools. It only shows jobs started from the current shell that are still known to its job control system.
Moving a foreground job to the background
Sometimes you start a command in the foreground and then realize you want your prompt back. The shell allows you to suspend the job, then continue it in the background.
First, you suspend the foreground job with the terminal interrupt for suspension, typically Ctrl+Z. This does not kill the job but sends a signal that stops it temporarily. The shell reports that the job is stopped and returns a prompt.
Then you can resume the job in the background with:
bgIf there are multiple stopped jobs, you can specify one using its job number, for example:
bg %2From that point, the job continues running but the shell remains interactive.
To move a running foreground job to the background:
- Press
Ctrl+Zto stop it. - Run
bgto resume it in the background.
Bringing a background job to the foreground
You may have a job running in the background that you now want to interact with or monitor more closely. To bring a job back to the foreground, use the fg builtin:
fg
Without arguments, fg brings the most recent job to the foreground. To specify a particular job, use its job number:
fg %1
The selected job now regains control of the terminal. You can interact with it as usual, and use Ctrl+C or Ctrl+Z as you would with a command you started in the foreground.
Stopped jobs and signals from the terminal
When you type Ctrl+Z, the terminal sends a stop signal to the foreground process group. This stops the job and the shell marks it as Stopped. The job remains in memory but does not run until you resume it with bg or fg.
When you type Ctrl+C, the terminal sends an interrupt signal to the foreground process group. This usually terminates the job immediately. That belongs to general signal handling, but it is closely related to how foreground jobs respond to your keyboard.
Stopped jobs still occupy resources, such as memory and a slot in the jobs list, and they are not doing useful work until they are resumed.
Monitoring job completion
When a background job finishes, most shells print a notification. It typically shows the job number, state such as Done, and the original command. This can appear while you are typing or after the next command, depending on the shell and its settings.
To cleanly remove completed jobs from the jobs table, you can use jobs again. In some shells, there are options to remove or disown jobs, which affects how they are tracked, but the basic idea is that a background job continues until it exits or is terminated, and the shell lets you know that it is done.
Exiting the shell with active jobs
When you try to exit a shell that has running or stopped jobs, some shells warn you. The warning exists to prevent you from accidentally leaving long running work behind or losing track of stopped programs.
If you exit anyway, background jobs that are still attached to the terminal may receive a signal tied to their control terminal disappearing. In some setups they terminate as a result. Handling this situation in a more advanced way involves disowning jobs and using the terminal in different modes, which builds on the basic concepts described here.
For safe interactive use, it is good practice to either wait for important background jobs to finish, or move them to a context where their life cycle is not tied to a single interactive shell before you log out.