The jobs command in Linux: list background jobs

Introduction

In the Linux command-line environment, it is common to launch processes that continue running while we keep working in the terminal. These processes can stay in the foreground or move to the background, allowing us to keep typing commands without waiting for them to finish. The jobs command is a built-in tool in most shells (such as Bash and Zsh) that displays the list of those background jobs, indicating their state and identification number. Knowing its use is essential for efficiently managing multiple tasks from a single session.

What is a background job?

A background job is any process that is started from the shell and placed in execution mode without blocking the terminal’s standard input. By adding an ampersand (&) at the end of a command, we tell the shell to execute it in the background and immediately return the prompt. Jobs can be in different states: running, stopped (for example, by sending SIGTSTP with Ctrl+Z) or finished. The shell maintains an internal table of jobs where each receives a job number (job ID) distinct from the process PID, making it easy to reference using the % symbol followed by the number.

Syntax of the jobs command

The basic syntax of the jobs command is very simple:

jobs [options] [jobID…]

If no option or jobID is specified, jobs displays all jobs known to the current shell. The most common options allow filtering the output, showing the associated PID, or changing the display format. Below we describe the most useful options and some practical examples that illustrate everyday use.

Most useful options

  • -l: Lists the PID of each job together with its job number and state. Very useful when you need to know the process identifier to send signals with kill.
  • -n: Shows only the jobs that have changed state since the last notification. Ideal for scripts that want to react to changes without processing the whole list.
  • -p: Shows only the PID of each job, one per line, making it easy to capture in pipelines.
  • -r: Restricts output to jobs that are currently running.
  • -s: Shows only jobs that are stopped.

These options can be combined; for example, jobs -l -r displays the PID and job number of running processes.

Practical examples

Imagine you are compiling a large project and want to continue editing files while the compilation proceeds. You can launch the compilation in the background:

make &

Then, with jobs you see something like:

[1] + 12345 running make

The number in brackets is the job ID (1) and the + sign indicates the job to which you will return if you run fg without arguments. If you want to see the PID, use:

jobs -l

Output:

[1] + 12345 running make

If you send the job to the background after stopping it with Ctrl+Z, you can resume it with:

bg %1

And to bring it back to the foreground:

fg %1

Another typical case is running a development server in the background:

python3 -m http.server 8000 &

You can then check its status with jobs and, when you no longer need it, stop it with kill %1 or bring it to the foreground and terminate it with Ctrl+C.

Managing jobs with fg and bg

The jobs command only lists; to interact with jobs we use fg (foreground) and bg (background). fg %n brings job n to the foreground, allowing you to interact with it directly. If the number is omitted, fg acts on the job marked with + (the last one that was in the background). Conversely, bg %n resumes a stopped job in the background. These commands are especially useful when, after pressing Ctrl+Z, you want to continue execution without blocking the terminal. Remember that fg and bg only work on jobs controlled by the current shell; they do not affect processes started outside of it.

Best practices and tips

  • Always check the output of jobs before killing a job; using kill %n is safer than kill because it avoids mistakes if the PID has been reused.
  • In scripts, combine jobs -p with read to capture the PIDs of specific jobs and act on them.
  • Avoid leaving background jobs running indefinitely; if you no longer need them, terminate them to free resources.
  • In production environments, consider using tools like nohup or disown to detach processes from the terminal and prevent them from receiving SIGHUP when the session ends.
  • Take advantage of the -n option of jobs in monitoring loops to detect state changes without overloading the CPU.

Conclusion

The jobs command is an essential piece of any Linux user’s toolkit when working with the terminal. Its simplicity allows you to quickly get a clear view of background processes, while its options and combination with fg and bg provide precise control over their execution. Mastering jobs not only improves productivity by avoiding unnecessary waits, but also contributes to a more orderly and secure management of system resources. The next time you launch a process with &, remember to check jobs to keep everything under control.

This post is also available in ESPAÑOL.

Leave a Reply

Your email address will not be published. Required fields are marked *

Esta obra está bajo una Licencia Creative Commons Atribución 4.0 Internacional para Francesc Roig francesc@vivaldi.net .