BudiBadu Logo
Samplebadu

Bash by Example: Background Processes

Bash 5.0+

Running commands asynchronously using the ampersand operator to launch background jobs, managing multiple parallel tasks with the jobs built-in command, understanding job control with fg and bg, and using wait to synchronize completion of background processes.

Code

#!/bin/bash

echo "Starting long tasks..."

# Run tasks in background with &
sleep 3 &
echo "Task 1 started (PID: $!)"

sleep 5 &
echo "Task 2 started (PID: $!)"

# List current jobs controlled by this shell
echo -e "\n--- Job List ---"
jobs -l

echo -e "\nWaiting for all tasks..."
# 'wait' without arguments waits for ALL background jobs
wait

echo "All tasks finished."

Explanation

By default, Bash executes commands synchronously—it runs a command, waits for it to finish, and then moves to the next line. However, modern shell scripting often requires running tasks in parallel or keeping the shell responsive while a long task runs. Appending an ampersand & to a command tells Bash to execute it in the background as a sub-process, allowing the script to continue immediately to the next command without waiting.

When a command is sent to the background, Bash assigns it a "Job ID" (e.g., [1]) and prints its Process ID (PID). You can view these active background tasks using the jobs command. In interactive sessions, job control is particularly powerful: you can suspend a foreground process with Ctrl+Z, send it to the background with bg, and later bring it back to the foreground with fg. This is useful when you start a long-running command and realize you need the terminal for other work.

In scripting, background processes are essential for performance optimization. If you need to download 10 files, compress 5 directories, or run several independent database queries, doing them sequentially is inefficient. By launching all tasks in the background and then using wait, you can process them in parallel, dramatically reducing total execution time. Background processes also allow services and daemons to run independently. Commands like nohup and disown can further detach processes so they survive even after the parent shell exits.

Code Breakdown

6-7
The & operator detaches the command. The script continues immediately to the next line without waiting for sleep 3 to finish. $! captures the PID.
9-10
A second task is launched in the background. Both Task 1 and Task 2 are now running simultaneously.
14
jobs -l lists the active jobs started by the current shell, showing both their Job ID (used by fg/bg) and their system PID.
18
wait pauses the script until all background jobs have completed. This ensures the script doesn't exit prematurely, killing its child processes.