Bash: The jobs Builtin — Managing Background and Stopped Jobs

Learn how to use Bash’s jobs builtin to list, inspect, and manage background and stopped commands. Explore useful options and see how fg and bg help you control jobs directly from your terminal.

Bash: The jobs Builtin — Managing Background and Stopped Jobs

Have you ever started a command in the terminal, sent it to the background, or pressed Ctrl+Z and wondered where your command went?

Bash has a built-in command to help: jobs.

It lists the jobs managed by your current shell, showing which are running and which have been stopped. Combined with fg and bg, it gives you a simple way to manage multiple commands without opening additional terminals.

Let's see how it works.

1. Jobs vs. Processes

Before using jobs, it's worth understanding the difference between a job and a process.

A process is a running instance of a program. Every process has a process ID (PID), which the operating system uses to identify it.

A job is a command or pipeline that Bash manages within a particular shell session. For example, when you start a command in the background, Bash assigns it a job number.

Try this:

sleep 600 &

Bash might print:

[1] 12345

Here, [1] is the job number, and 12345 is the process ID. Your actual numbers will probably be different.

The job number is used by Bash job-control commands, while the PID identifies a process in the operating system. Job numbers are local to a shell, so job %1 in one terminal is not necessarily related to job %1 in another.

2. Listing Jobs with jobs

To see the jobs managed by your current shell, simply run:

jobs

Example output:

[1]+  Running                 sleep 600 &
[2]-  Stopped                 vim notes.txt

Each line includes the job number, a status, and the command associated with the job.

  • [1] — The job number.
  • + — The current job, generally the default for job-control commands when no job is specified.
  • - — The previous job.
  • Running — The job is running.
  • Stopped — The job has been suspended, often after pressing Ctrl+Z.

The exact output depends on which jobs you have started and their current states.

3. Useful jobs Options

The jobs builtin supports several options that let you customize its output.

Show process IDs: jobs -l

Use -l when you need to see the PIDs alongside the job information:

jobs -l

Example output:

[1]+ 12345 Running  sleep 600 &

This is useful when you want to inspect a job's process with another command, such as:

ps -p 12345

Replace the example PID with the one shown on your system.

Show only process IDs: jobs -p

If you need only the PIDs associated with your jobs, use:

jobs -p

This can be handy in shell scripts when you need to capture process IDs. Remember that it reports processes associated with jobs known to the current shell, not every process running on the system.

Show only running jobs: jobs -r

To list jobs that are currently running:

jobs -r

Stopped jobs are excluded from the output.

Show only stopped jobs: jobs -s

To list jobs that have been suspended:

jobs -s

A stopped job hasn't necessarily finished. It may be resumed later using fg or bg.

Show jobs with changed status: jobs -n

The -n option displays jobs whose status has changed since Bash last reported it:

jobs -n

For example, this can help identify a background job that has finished. However, jobs -n doesn't continuously monitor jobs; it reports changes when you run the command. Bash may also have already reported a status change at the terminal prompt.

Inspect a specific job

You can specify a job by its number:

jobs %1

This displays information about job 1. The % prefix identifies a Bash job specification, rather than a process ID.

4. Managing Jobs with fg and bg

The jobs command displays information but doesn't change a job's state. Two other Bash builtins let you resume jobs in different ways.

Suspend and resume a command

Start a command in the foreground:

sleep 600

Press Ctrl+Z. Bash suspends the command and returns you to the prompt.

Now check the job list:

jobs

You should see the command marked as Stopped.

To resume it in the foreground, use:

fg %1

Bash brings job 1 back to the foreground. The terminal is occupied by the command until it finishes or you suspend or interrupt it again.

Resume a job in the background

If you want the stopped command to continue without taking over your terminal, use:

bg %1

Bash resumes the job in the background, allowing you to continue working.

You can confirm its state with jobs.

If you omit the job number from fg or bg, Bash generally uses the current job, marked with + in the job listing.

One thing to remember: some programs need interactive terminal input and may not work as expected in the background. Background execution is most convenient for commands that can run without interacting with you.

5. What Happens When a Job Finishes?

Background jobs eventually finish, and Bash may display a notification such as:

[1]+  Done                    sleep 2

Once Bash has processed and reported the completion, the job normally disappears from the active job list.

You can try it yourself:

sleep 2 &
jobs

Wait a few seconds, then run jobs again. The job may no longer appear.

This is different from a stopped job: a stopped job remains available to resume, while a completed job has finished executing.

6. Important Limitations

There are a few details worth keeping in mind:

  • jobs is not a system-wide process list. It shows jobs managed by the current shell. Use ps or top to inspect processes across the system.
  • Job numbers can change. They are assigned by Bash and shouldn't be treated as permanent identifiers.
  • jobs doesn't stop or terminate anything. Use fg and bg to resume jobs, or kill when you need to send a signal.
  • Scripts behave differently from interactive shells. Job control is primarily designed for interactive terminal sessions. For scripts that launch background commands, managing PIDs and using wait is often more predictable.

Quick Reference

CommandPurpose
jobsList jobs managed by the current shell
jobs -lInclude process IDs
jobs -nShow jobs with status changes since the last report
jobs -pPrint process IDs associated with jobs
jobs -rList running jobs
jobs -sList stopped jobs
jobs %1Display job 1
fg %1Bring job 1 to the foreground
bg %1Resume job 1 in the background
kill %1Send a signal to job 1

Conclusion

The jobs builtin makes it easy to keep track of background and stopped commands in Bash. It shows you what your current shell is managing and provides the job numbers you need to resume or control those commands.

Remember the distinction: a job is managed by your shell, while a process is identified by the operating system through its PID.

Once you understand that difference, jobs, fg, and bg become straightforward tools for managing multiple tasks from a single terminal. And the next time you press Ctrl+Z by accident, just run `jobs — your command may still be there, waiting for you to decide what to do next.

Read next

Bash — Variables and Parameter Expansion

Learn how Bash variables work, from basic assignments and default values to advanced parameter expansion. Discover how to manipulate strings, extract substrings, replace text, change letter case, and use variables more effectively in your scripts.