Skip to main content
Shell Scripting – Complete Beginner to Advanced Guide
CHAPTER 12 Intermediate

Process Management in Shell Scripts

Updated: May 16, 2026
25 min read

# CHAPTER 12

Process Management in Shell Scripts

1. Introduction

When you execute a command like sleep 100, the terminal hangs. You cannot type anything else until those 100 seconds have passed. The program has seized complete control of the foreground. In modern system administration, scripts often need to trigger multiple massive tasks simultaneously—like downloading a large file while simultaneously compressing a database backup. To achieve this, a script must be able to push tasks into the background, monitor their execution status, and forcefully terminate them if they freeze. In this chapter, we will master Unix Process Management. We will learn to list active processes using ps, manage background execution using the Ampersand (&), and enforce administrative authority by annihilating rogue tasks using the kill command.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Identify and monitor active system processes using the ps and top commands.
  • Send a script or command to execute silently in the background using &.
  • Retrieve the unique Process ID (PID) of background tasks using $!.
  • Terminate hanging or rogue processes safely using the kill command.
  • Understand the distinction between graceful termination (kill -15) and forceful termination (kill -9).

3. Monitoring Processes (ps)

Every single program running on a Unix system (even the shell itself) is assigned a unique number called a Process ID (PID). To see what is running, you use the ps (Process Status) command.
sh
123456
# View processes running in your current terminal
ps

# The Holy Grail: View EVERY process running on the entire server
# a = all users, u = show user/memory details, x = show background processes
ps aux

If you are looking for a specific running script, you pipe the massive ps aux output directly into grep: ps aux | grep "backup.sh"

4. Background Execution (& and nohup)

If you want to run a long task without locking up your script, simply append an Ampersand (&) to the end of the command. The shell will instantly throw the task into the background and proceed to the next line of your script.
sh
123456
#!/bin/sh
echo "Initiating massive download..."
# The & sends the wget download to the background
wget http://example.com/massive_file.iso &

echo "Download is running in the background. I am free to do other work!"

*The Disconnect Problem:* If you start a background task and then log out of your SSH session, the task will die. To prevent this, use nohup (No Hangup).

sh
1
nohup ./long_script.sh &

5. Tracking the PID ($!)

When a script throws a task into the background, it often needs to know the PID of that task so it can check on it later. The shell automatically stores the PID of the most recently backgrounded task in a special variable: $!.
sh
1234567
#!/bin/sh
echo "Starting background backup..."
./slow_backup.sh &

# Capture the PID
BACKUP_PID=$!
echo "Backup is running under PID: $BACKUP_PID"

6. Terminating Processes (kill)

If a script freezes (e.g., a network connection times out infinitely), you must terminate the process using the kill command followed by the PID.

There are two primary ways to kill:

  1. 1. Graceful (kill -15 or SIGTERM): This asks the program nicely to shut down. The program is allowed to save its files and close its connections before dying. (This is the default if you just type kill 1234).
  1. 2. Forceful (kill -9 or SIGKILL): This is the nuclear option. The kernel instantly executes the program without warning. Data corruption may occur.

sh
12345
# Gracefully ask PID 5432 to stop
kill 5432

# Forcefully annihilate PID 5432
kill -9 5432

7. Diagrams/Visual Suggestions

*Visual Concept: Foreground vs Background Execution* Draw a terminal screen divided into two halves. Foreground (Top): A person typing sleep 100. The terminal shows a spinning hourglass. A red stop sign says "Terminal Locked." Background (Bottom): A person typing sleep 100 &. A smaller gear icon spins in the corner, while the main terminal shows an active, blinking $ prompt ready for new commands. This visualizes the operational freedom granted by background job management.

8. Best Practices

  • Always try kill before kill -9: In a script, if you need to restart a service, you should attempt a graceful kill first, followed by a short sleep 2 to give it time to die, before escalating to the destructive kill -9 command. This preserves database integrity and prevents corrupt cache files.

9. Common Mistakes

  • Killing the grep process: If you type ps aux | grep my_script, the terminal often returns *two* lines. One is your script, and the other is the grep command itself (because grep is currently running to search for the word!). Beginners often accidentally grab the PID of the grep process and try to kill it, resulting in a confusing "No such process" error.

10. Mini Project: The Timeout Sentinel

Let's build a script that starts a task, waits 5 seconds, and if the task isn't finished, forcefully kills it.
  1. 1. nano sentinel.sh
  1. 2. Write the code:
sh
123456789101112131415161718192021
#!/bin/sh

echo "Starting risky network task..."

# 1. Start a task that will intentionally hang (sleep 10) in the background
sleep 10 &
TASK_PID=$!

echo "Task running with PID: $TASK_PID"
echo "Waiting 5 seconds for completion..."
sleep 5

# 2. Check if the task is still running
# 'kill -0' doesn't actually kill. It just checks if the PID exists!
if kill -0 $TASK_PID 2>/dev/null; then
    echo "TIMEOUT REACHED! Task is hanging. Executing SIGKILL..."
    kill -9 $TASK_PID
    echo "Task terminated."
else
    echo "Task finished successfully on its own."
fi
  1. 3. Run it. You have engineered an active timeout monitor that prevents rogue processes from permanently freezing your system!

11. Practice Exercises

  1. 1. Explain the operational difference between executing a script using the command ./script.sh versus nohup ./script.sh &.
  1. 2. Detail the critical distinction between the kill -15 signal and the kill -9 signal. Why is -9 considered the absolute last resort?

12. MCQs with Answers

Question 1

A system administrator needs to identify the unique Process ID (PID) of a heavily consuming background script named "indexer". Which command pipeline is universally utilized to locate this specific process among all running applications?

Q2. Immediately after initiating a long-running database sync in the background using the Ampersand (&), which specialized shell variable will securely contain the newly generated Process ID of that specific task? a) $# b) $@ c) $$ d) $! Answer: d) $!

13. Interview Questions

  • Q: A developer complains that their automated reporting script successfully starts a background task, but the background task instantly dies the moment their SSH session disconnects from the server. Explain the mechanism causing this termination, and provide the exact command syntax required to immunize the background task against session disconnection.
  • Q: Walk me through the exact terminal workflow you would execute if you discovered a script was trapped in an infinite while loop, consuming 100% of a CPU core, and completely ignoring standard Ctrl+C termination attempts.
  • Q: Explain the purpose of the kill -0 command when utilized inside a shell script. Why is it an essential tool for monitoring the lifespan of background jobs?

14. FAQs

Q: Can I bring a background process back into the foreground so I can see its output? A: Yes! If you start a job with &, you can type jobs to see a numbered list of your background tasks. You can then type fg %1 (Foreground Job 1) to instantly yank the task back into your active terminal window.

15. Summary

In Chapter 12, we mastered the dimension of multitasking within the Unix operating system. We learned to interrogate the kernel using the ps aux pipeline, identifying the unique Process IDs (PIDs) that define all running software. We liberated our scripts from linear execution delays by deploying the Ampersand (&), throwing massive workloads into the background while utilizing $! to dynamically track their status. Finally, we enforced administrative discipline, establishing strict timeout protocols and utilizing the kill command to gracefully (-15) or forcefully (-9) terminate rogue processes that threaten system stability.

16. Next Chapter Recommendation

Your script can successfully start tasks, throw them into the background, and manage their lifespans. But to achieve absolute, hands-free automation, we must hand control of the script over to the Linux timekeeper itself. Proceed to Chapter 13: Scheduling Tasks with Cron.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·