Understanding Job Control in Bash Scripting

Mahesh GaikwadMahesh Gaikwad
3 min read

Job control in Bash allows you to manage processes running in your terminal. You can stop, continue, or move jobs between the foreground and background. This feature is particularly useful when you are multitasking in the terminal.

What is Job Control?

Job control helps you:

  • Suspend processes (stop them temporarily).

  • Resume processes (restart them after suspension).

  • Move jobs between foreground and background.

Bash assigns a unique number (called a job number) to each job. You can view the running jobs using the jobs command. When you run a job in the background, Bash shows the job number and the process ID.

[1] 25647

Here, job number 1 has the process ID 25647.

Foreground vs. Background Jobs

  • Foreground jobs are processes you can interact with directly. For instance, if you run a program and use your keyboard to send inputs, it’s a foreground process.

  • Background jobs are processes running behind the scenes, and they don't get inputs from the terminal. You can run jobs in the background by adding & at the end of a command.

Example Bash Script for Job Control

Let's look at a simple Bash script that demonstrates job control:

#!/bin/bash

# Function to simulate a long-running process
long_running_task() {
    echo "Task $1 started (PID: $$)"
    for i in {1..5}; do
        echo "Task $1 is running step $i"
        sleep 2
    done
    echo "Task $1 completed!"
}

# Start two tasks in the background
echo "Starting Task 1 in the background..."
long_running_task 1 &    # Start task 1 in background
task1_pid=$!
echo "Task 1 is running with PID: $task1_pid"

echo "Starting Task 2 in the background..."
long_running_task 2 &    # Start task 2 in background
task2_pid=$!
echo "Task 2 is running with PID: $task2_pid"

# List the current jobs
echo
echo "Listing the running jobs:"
jobs

# Wait for a few seconds, then bring Task 1 to the foreground
sleep 3
echo
echo "Bringing Task 1 to the foreground..."
fg %1    # Bring Task 1 to the foreground

# After Task 1 is done, stop Task 2
echo
echo "Stopping Task 2 (sending it to the background)..."
kill -SIGTSTP $task2_pid    # Stop Task 2 temporarily

# List jobs again to show the status
echo
echo "Listing jobs again (Task 2 should be stopped):"
jobs

# Resume Task 2 in the background
echo
echo "Resuming Task 2 in the background..."
bg %2    # Resume Task 2 in the background

# Wait for all background jobs to complete
echo
echo "Waiting for all background jobs to complete..."
wait

echo "All tasks completed!"

Explanation of the Script

  1. Starting Tasks in the Background:

    • We run two tasks in the background using the & symbol. Each task has its own process ID, which is stored in $!.
  2. Foreground and Background Control:

    • fg %1 brings Task 1 to the foreground. This means you can interact with it directly.

    • We suspend Task 2 using kill -SIGTSTP, which stops it temporarily.

  3. Managing Jobs:

    • The jobs command lists all current jobs with their status (running or stopped).

    • We resume Task 2 with bg %2, allowing it to continue in the background.

Job Control Commands

  • jobs: Lists all running and stopped jobs.

  • fg %n: Brings job number n to the foreground.

  • bg %n: Resumes job number n in the background.

  • kill -SIGTSTP [PID]: Suspends a process (like pressing Ctrl+Z).

  • wait: Waits for all background processes to finish.

By understanding these concepts and using the script, you can effectively manage processes using job control in Bash.

0
Subscribe to my newsletter

Read articles from Mahesh Gaikwad directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Mahesh Gaikwad
Mahesh Gaikwad