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] 12345Here, [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:
jobsExample output:
[1]+ Running sleep 600 &
[2]- Stopped vim notes.txtEach 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 pressingCtrl+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 -lExample 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 12345Replace 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 -pThis 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 -rStopped jobs are excluded from the output.
Show only stopped jobs: jobs -s
To list jobs that have been suspended:
jobs -sA 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 -nFor 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 %1This 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 600Press Ctrl+Z. Bash suspends the command and returns you to the prompt.
Now check the job list:
jobsYou should see the command marked as Stopped.
To resume it in the foreground, use:
fg %1Bash 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 %1Bash 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 2Once Bash has processed and reported the completion, the job normally disappears from the active job list.
You can try it yourself:
sleep 2 &
jobsWait 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:
jobsis not a system-wide process list. It shows jobs managed by the current shell. Usepsortopto inspect processes across the system.- Job numbers can change. They are assigned by Bash and shouldn't be treated as permanent identifiers.
jobsdoesn't stop or terminate anything. Usefgandbgto resume jobs, orkillwhen 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
waitis often more predictable.
Quick Reference
| Command | Purpose |
|---|---|
jobs | List jobs managed by the current shell |
jobs -l | Include process IDs |
jobs -n | Show jobs with status changes since the last report |
jobs -p | Print process IDs associated with jobs |
jobs -r | List running jobs |
jobs -s | List stopped jobs |
jobs %1 | Display job 1 |
fg %1 | Bring job 1 to the foreground |
bg %1 | Resume job 1 in the background |
kill %1 | Send 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.