Cybersecurity Updates & Tools

jobs Command in Linux: List and Manage Background Processes

The jobs command is a Bash builtin that lists all background and suspended processes belonging to the current shell session. It shows the job number, state, and command for each job, and works together with fgbgkill, and disown to give you full control over those processes.

How to Use the jobs Command in Linux

The syntax is:

bashjobs [OPTIONS] [JOB_SPEC...]

Run without arguments to see all active jobs:

bashjobs

Sample output with two jobs — one stopped and one running:

[1]-  Stopped                 vim notes.txt[2]+  Running                 ping google.com &

Each line shows four things: the job number in brackets, a + or - marker, the job state, and the command that started the job.

The + marks the current job – the one that fg and bg will act on by default when no job spec is given. The - marks the previous job. When the current job finishes, the previous job becomes the new current job.

Job states:

  • Running – executing in the background
  • Stopped – suspended, typically by pressing Ctrl+Z
  • Done – finished; appears once in the output, then disappears from the list
  • Terminated – killed by a signal

Done is worth noting: the shell does not display it immediately. You see it the next time you press Enter or run another command.

Add PIDs to the output with -l:

bashjobs -l

The PID is shown between the marker and the state. Useful when you need to signal a specific process with kill.

Other options:

  • -r – list only running jobs
  • -s – list only stopped jobs
  • -p – print only the PID of each job’s process group leader
  • -n – show only jobs whose status changed since the last notification

Job Specifications and Targeting Specific Jobs

Job specifications (job specs) let you target a specific job in fgbgkill, and disown. They always start with %:

SpecTargets
%1%2Job by number
%+ or %%Current job (marked with +)
%-Previous job (marked with -)
%stringJob whose command starts with that string
%?stringJob whose command contains that string anywhere

The difference between %string and %?string matters when the keyword appears mid-command. %ping matches a job started with ping google.com%?google also matches it because “google” appears anywhere in the command.

Bring job 1 to the foreground by number or prefix — both work:

bashfg %1fg %sleep

Remove a job from the shell’s job table so it survives terminal close:

bashdisown %1

After disown, the shell no longer tracks the job and will not send SIGHUP to it when the terminal closes.

Using jobs in Scripts and Keeping Jobs Alive

Job control is disabled by default in shell scripts. Running jobs inside a script returns nothing, even when background processes exist. In scripts, use $! to capture the PID of the last backgrounded command, then use wait with the PID:

bashlong_task &task_pid=$!# Check if the process is still runningwhile kill -0 "$task_pid" 2>/dev/null; do  echo "Still running..."  sleep 5doneecho "Done."

kill -0 sends no signal. It only checks whether the process exists. Exit code 0 means it is running; any other exit code means it has stopped.

To wait for several parallel background tasks before continuing:

bashtask_a & pid_a=$!task_b & pid_b=$!wait "$pid_a" "$pid_b"echo "Both complete."

To keep a job alive after closing the terminal, use nohup before starting it or disown after backgrounding it. For long-running interactive sessions, screen or tmux are better choices.

Use jobs to see what is running in your shell, job specs with % to target them, and $! with wait when writing scripts. Leave a comment below if you run into any issues.