LFCS 57 ๐ง Background Jobs โ &, bg, fg, jobs
A shell session is not limited to running one command at a time. Job control is the mechanism that lets you start a process in the background, suspend a foreground process, resume it later, and list everything the shell is managing. The ampersand (&) starts a command asynchronously, returning the prompt immediately while the process runs in the background. Ctrl+Z suspends the foreground process and returns control to the shell. bg resumes a suspended job in the background, fg brings it back to the foreground, and jobs lists every job the shell is tracking . The LFCS exam expects you to know all four, because “manage or schedule jobs for executing commands” is an explicit objective in the Operations Deployment domain .
The distinction between a job and a process is the first thing to internalize. A job is a shell-level abstraction: it is a pipeline, and all the processes in that pipeline belong to the same job. The shell assigns each job a job number (starting at 1), and that number is how you refer to it with %1, %2, and so on . The jobs command lists the jobs, fg %1 brings job 1 to the foreground, and bg %1 resumes it in the background. The process ID is a separate identifier, and jobs -l shows both.
Key point: command & starts a job in the background. Ctrl+Z suspends the foreground job. bg %n resumes a suspended job in the background, fg %n resumes it in the foreground, and jobs lists the shell’s jobs. A background job cannot read from the terminal; if it tries, the terminal driver sends SIGTTIN and suspends it .
Why job control exists
The terminal ownership problem. A terminal can have exactly one foreground process group at a time. That group receives the keyboard-generated signals (SIGINT from Ctrl+C, SIGTSTP from Ctrl+Z) and has read/write access to the terminal. Background processes are in a different process group, so they are immune to those signals, but they are also denied read access: if a background process tries to read from the terminal, the driver sends SIGTTIN, which suspends it unless the process catches the signal . This is why vim & does not workโvim needs terminal input, and the shell suspends it immediately.
The long-running task problem. A compile, a download, or a database dump can take minutes or hours. Running it in the foreground blocks the shell, and the user cannot run any other command. The & operator returns the prompt immediately and prints a line like [1] 25647, where 1 is the job number and 25647 is the PID of the last process in the pipeline . The shell continues to track the job, and jobs shows its status.
The interruption problem. Sometimes a task is already running in the foreground and you realize you need the shell backโto check a log, to answer a question from a colleague, to start another command. Ctrl+Z sends SIGTSTP to the foreground process group, which stops the processes and returns control to the shell . The job is now in the “Stopped” state. bg resumes it in the background, fg resumes it in the foreground.
The job reference problem. A shell session can have many jobs. The job number is the short identifier, but the shell also supports references by command prefix: %ce refers to the stopped ce job, and %?ce refers to any job containing ce in its command line. The current job is %% or %+, and the previous job is %- . The + and - flags in the jobs output identify the current and previous jobs.
a. Starting a background job with &
The ampersand at the end of a command starts it asynchronously. The shell forks, the child runs the command, and the parent returns the prompt. The shell prints the job number and the PID.
# Start a long-running command in the background
# The & at the end makes it asynchronous
# The shell prints the job number and PID
sleep 300 &
# Output: [1] 12345
# [1] is the job number
# 12345 is the PID
# The prompt returns immediately
# The sleep process runs in the background
# Start a pipeline in the background
# The whole pipeline is one job
# The PID is the last process in the pipeline
find / -name "*.log" 2>/dev/null | gzip > logs.gz &
# Output: [2] 12346
The job number is assigned in sequence. The first background job is [1], the second is [2], and so on. The PID is the process ID of the last command in the pipeline, not the first . For a single command, they are the same. For a pipeline, the shell tracks the job by the pipeline as a whole, and the jobs command shows the job number and the status.
The background job’s output still goes to the terminal unless it is redirected. A background job that writes to stdout will interleave its output with the shell prompt. The standard practice is to redirect the output to a file or to /dev/null .
b. Suspending and resuming with Ctrl+Z, bg, and fg
Ctrl+Z suspends the foreground job. The process is stopped, not killed; it can be resumed. The shell prints a line like [1]+ Stopped sleep 300 and returns the prompt.
# Run a command in the foreground
sleep 300
# Press Ctrl+Z
# The shell suspends the sleep process
# Output: [1]+ Stopped sleep 300
# The prompt returns
# The job is in the Stopped state
# Resume the job in the background
bg %1
# Output: [1]+ sleep 300 &
# The process is now running in the background
# Bring the job back to the foreground
fg %1
# The shell is now waiting for the sleep to finish
# Press Ctrl+C to interrupt it
The bg command resumes a suspended job as if it had been started with & . If the job is already running in the background, bg has no effect and returns success. The fg command resumes the job in the foreground and makes it the current job . If the job is running in the background, fg moves it to the foreground, which means it regains terminal access and becomes subject to Ctrl+C and Ctrl+Z.
The job specification is optional. fg with no argument resumes the current job, which is the one marked with + in the jobs output. bg with no argument does the same. The %1 form is the explicit reference, and %1 & is a synonym for bg %1 .
c. Listing and managing jobs with jobs
The jobs command lists the shell’s jobs. The output shows the job number, the state (Running, Stopped), and the command line.
# Start two background jobs
sleep 100 &
# Output: [1] 12347
sleep 200 &
# Output: [2] 12348
# List the jobs
jobs
# Output:
# [1]- Running sleep 100 &
# [2]+ Running sleep 200 &
# The + marks the current job
# The - marks the previous job
# List with PIDs
jobs -l
# Output:
# [1]- 12347 Running sleep 100 &
# [2]+ 12348 Running sleep 200 &
# List only running jobs
jobs -r
# List only stopped jobs
jobs -s
The -l flag adds the PID to the output. The -r and -s flags filter by state: -r shows only running jobs, and -s shows only stopped jobs . The -n flag shows only jobs whose status has changed since the last notification, which is useful in a script that polls for completion.
The + and - markers are not decoration. The + job is the current job, and fg or bg with no argument operates on it. The - job is the previous job, and %- refers to it. When the current job is terminated, the - job becomes the current job.
The kill command works with job specifications as well as PIDs. kill %1 sends SIGTERM to the job’s process group, which terminates the whole pipeline . The %1 form is the job reference, and the shell translates it to the process group ID.
Complete Example Session
The following session starts a background job, suspends a foreground job, resumes it in the background, lists the jobs, and brings one back to the foreground.
# ============================================
# PART 1: START A BACKGROUND JOB
# ============================================
# The sleep runs in the background
# The shell prints the job number and PID
sleep 300 &
# Output: [1] 12345
# ============================================
# PART 2: START A FOREGROUND JOB AND SUSPEND IT
# ============================================
# Run a foreground command
top
# Press Ctrl+Z
# The top process is suspended
# Output: [2]+ Stopped top
# ============================================
# PART 3: LIST THE JOBS
# ============================================
jobs
# Output:
# [1]- Running sleep 300 &
# [2]+ Stopped top
# The + is the current job (top, because it was just suspended)
# The - is the previous job (sleep)
# ============================================
# PART 4: RESUME THE SUSPENDED JOB IN THE BACKGROUND
# ============================================
# Resume top in the background
# It will fail to read the terminal and suspend again
bg %2
# Output: [2]+ top &
# The top process tries to read the terminal
# The terminal driver sends SIGTTIN
# The process is suspended again
# Output: [2]+ Stopped top
# ============================================
# PART 5: BRING A JOB TO THE FOREGROUND
# ============================================
# Bring the sleep job to the foreground
fg %1
# The shell waits for the sleep to finish
# Press Ctrl+C to interrupt it
# Output: ^C
# ============================================
# PART 6: CHECK AND CLEAN UP
# ============================================
jobs
# Output:
# [2]+ Stopped top
# Kill the stopped job
kill %2
# The job is terminated
jobs
# Output: (empty)
The six parts cover starting a background job, suspending a foreground job, listing, resuming in the background, bringing to the foreground, and cleaning up. What the session demonstrates is that the & returns the prompt, Ctrl+Z stops the process, bg resumes it, fg brings it back, and jobs shows the state.
Quick Reference
Job Control Commands
| Command | Effect |
|---|---|
command & | Start in background |
Ctrl+Z | Suspend foreground job |
bg %n | Resume suspended job in background |
fg %n | Resume job in foreground |
jobs | List jobs |
Job States
| State | Meaning |
|---|---|
| Running | Executing in the background |
| Stopped | Suspended, can be resumed |
| Done | Completed |
Job References
| Reference | Meaning |
|---|---|
%n | Job number n |
%% or %+ | Current job |
%- | Previous job |
%string | Job whose command starts with string |
%?string | Job whose command contains string |
jobs Flags
| Flag | Effect |
|---|---|
-l | Show PIDs |
-r | Running jobs only |
-s | Stopped jobs only |
-n | Changed status only |
Best Practices
โ Do This:
# Start a long task in the background
./backup.sh &
# Suspend the foreground process
# Press Ctrl+Z
# Resume it in the background
bg
# List jobs with PIDs
jobs -l
# Bring the current job back
fg
โ Don’t Do This:
# Start a terminal-dependent app in the background
vim & # suspends immediately with SIGTTIN
# Forget the job number when multiple jobs exist
fg # resumes the current job, which may not be the one you want
# Assume the background job's output is suppressed
sleep 100 & # output still goes to the terminal
Common Pitfalls
| Pitfall | Why It Happens | Fix |
|---|---|---|
vim & suspends | Background job cannot read terminal | Run in foreground |
bg does nothing | Job already running in background | Check jobs |
fg wrong job | No job number, used current job | Use fg %n |
| Output interleaves | Background stdout not redirected | Redirect to file |
| Job lost after shell exit | Jobs are children of the shell | Use nohup or disown |
Real-World Examples
1. Start in background
./long-task.sh &
2. Suspend foreground
# Press Ctrl+Z
3. Resume in background
bg
4. Bring to foreground
fg
5. List jobs
jobs
6. List with PIDs
jobs -l
7. Kill a job
kill %1
8. Reference by name
fg %ce
9. Current job
fg %+
10. Previous job
fg %-
Visual
Job States
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ START โ
โ command & โ Running (background) โ
โ command โ Running (foreground) โ
โ โ โ
โ โผ โ
โ Ctrl+Z โ Stopped โ
โ โ โ
โ โโโโโโดโโโโโ โ
โ โ โ โ
โ โผ โผ โ
โ bg %n fg %n โ
โ โ โ โ
โ โผ โผ โ
โ Running Running โ
โ (background) (foreground) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Terminal Access
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ FOREGROUND โ
โ โ receives Ctrl+C, Ctrl+Z โ
โ โ can read/write terminal โ
โ โ
โ BACKGROUND โ
โ โ immune to keyboard signals โ
โ โ read attempt โ SIGTTIN โ suspend โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Job Reference
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ jobs โ
โ [1]- Running sleep 100 & โ
โ [2]+ Stopped top โ
โ โ
โ + = current job โ
โ - = previous job โ
โ โ
โ fg %2 โ bring top to foreground โ
โ kill %1 โ terminate sleep โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Summary
| Item | Value |
|---|---|
| Background start | command & |
| Suspend | Ctrl+Z |
| Resume in background | bg %n |
| Resume in foreground | fg %n |
| List jobs | jobs |
| List with PIDs | jobs -l |
| Kill job | kill %n |
| Current job | %+ or %% |
| Previous job | %- |
Key takeaways:
&starts a job in the background. The shell returns the prompt immediately and prints the job number and PID. The job continues running, and the shell tracks it .Ctrl+Zsuspends the foreground job. The process is stopped, not killed, and the shell returns the prompt. The job is in the “Stopped” state and can be resumed .bgresumes a suspended job in the background. It is equivalent to having started the job with&.fgresumes it in the foreground and gives it terminal access .- A background job cannot read the terminal. If it tries, the terminal driver sends
SIGTTINand suspends it. This is why interactive programs must run in the foreground . - The job number is the shell’s identifier.
%1refers to job 1,%+to the current job, and%-to the previous job. Thejobscommand shows the numbers and the+/-markers . - Jobs are children of the shell. When the shell exits, the jobs are terminated unless they are detached with
nohupordisown. Thenohupcommand makes the process immune to the hangup signal .
Remember: Job control is the shell’s mechanism for managing multiple tasks from a single terminal. The ampersand starts a job in the background, Ctrl+Z suspends the foreground job, bg and fg move it between the background and the foreground, and jobs lists what the shell is tracking. The terminal driver enforces the access rules: only the foreground job can read from the terminal, and a background job that tries is suspended. The job number is the short reference, and the + and - markers identify the current and previous jobs. The LFCS exam expects you to know these commands and the states, because they are the tools for managing the processes that a single shell session starts.
Stop using slow, ad-bloated tool sites! ๐คฎ
๐ Search “KandZ Tools” on Google to use many professional utilities for free.
KandZ.me is the ultimate minimalist hub for:
โ
Finance (Mortgage, Interest, Inflation)
โ
Tech (Base64, JSON, Dev Suite, IP)
โ
Health (BMI, BMR, TDEE)
โ
Productivity (Timer, Workspace, QR)
โก๏ธ Fast & Private
๐ No data leaves your device
๐ 100% Free
๐ Use it now: https://tools.kandz.me
๐ Bookmark itโyouโll need it later!