# Exercise: Stop the Runaway

Find and stop three misbehaving programs with ps, pgrep, kill and pkill, then write two small tools, one that stops any process the polite way before it uses force and one that starts a long export so it survives the terminal closing, and let a check script tell you what's done.

Journeyman · Unix · Linux · Updated November 10, 2026

It's the night before a deadline, and your laptop's fan is roaring. Three programs were left running in the background: a thumbnail maker stuck in a loop, an alarm that beeps every second, and a sync program that won't stop when it's asked nicely. Meanwhile, the video export you actually need has to keep going, even after you close the terminal. You'll find the three programs and stop each one the right way, then write two small tools so you never have to do it by hand again: `stop-politely.sh`, which stops any process the polite way before it uses force, and `start-export.sh`, which starts the export so it survives the terminal closing. A check script tells you what's done.

## Before you start

You need a terminal: the Terminal app on a Mac, or Ubuntu on Linux or in WSL on Windows. The check runs with **bats**, a small program that runs checks written for bash. If `bats --version` doesn't print a version number yet, install it:

```bash
sudo apt install bats       # Ubuntu, and Ubuntu in WSL
brew install bats-core      # a Mac, with Homebrew
```

`sudo` asks for your password, the one you use to sign in; nothing shows on the screen while you type it.

## Get the exercise code

Open this lesson's GitHub repository, [github.com/ask-codey/exercise-bash-stop-the-runaway](https://github.com/ask-codey/exercise-bash-stop-the-runaway), also linked from the **Exercise** box beside the lesson. Click **Code**, then **Download ZIP**, and unzip it into your `terminal-practice` folder. Or clone it with Git. On Windows, put it inside Ubuntu, in your Linux home folder, not in a Windows folder under `/mnt/c`, so `chmod` works on the scripts.

The folder holds:

- `answers.txt`: five questions, each with a numbered line for your answer.
- `stop-politely.sh` and `start-export.sh`: the two tools. Each starts with a comment that says exactly what it must do and print. These, and `answers.txt`, are the files you write.
- `start-the-mess.sh`: starts the three misbehaving programs in `mess/` in the background. Each one stops by itself after 30 minutes, in case you forget it.
- `clean-up.sh`: stops whatever the mess left running, if you get stuck.
- `export-video.sh`: the pretend export, one line a second for ten minutes.
- `check.bats`: the check. You don't need to change it.

Every program here is a practice program from this folder. Stop only these, and leave the rest of your computer's processes alone.

## What to do

Open a terminal in the exercise folder, make the scripts runnable, and start the mess:

```bash
chmod +x *.sh
./start-the-mess.sh
```

1. **Find the runaway.** Look at what's running with `ps aux --sort=-%cpu | head -n 5`, `pgrep -af mess/` or `top`, and answer questions 1 to 5 in `answers.txt` as you go. Write each answer after its `)`, like the example: `0) ps aux`.
2. **Stop the mess.** Stop the alarm with one `pkill` command, and the other two with `kill` and their PIDs. One of them won't stop the polite way. When they're all gone, `pgrep -af mess/` prints nothing.
3. **Write `stop-politely.sh PID`.** It sends TERM, checks once a second for up to five seconds, and sends KILL only if the process is still there. Try it on a fresh mess: run `./start-the-mess.sh` again, then `./stop-politely.sh` with each PID.
4. **Write `start-export.sh`.** It starts `./export-video.sh` in the background with `nohup`, sends its output into `export.log`, and saves its PID in `export.pid`. Run it, close the terminal, open a new one, and check with `pgrep -af export-video` that it's still going. Stop it with `pkill -f export-video` when you're done.

## Check your work

From the exercise folder:

```bash
bats check.bats
```

At first almost every check fails. That's expected: each question you answer and each job you finish turns its check into a ✓. The check tries your scripts on small practice processes of its own, in a throwaway folder, and stops only the processes it started. It takes about 20 seconds, because it waits the way your script does. A failing check says what to look at, for example *This practice process ignores TERM, and it's still running. After 5 seconds, send it KILL.*

## Hints

- **A script runs as `bash`**, so `pgrep` and `pkill` need `-f` to match the script's name in the whole command line (*Stopping Things: kill and Signals*).
- **Is it still running?** `ps -p "$1" > /dev/null` succeeds only while that process is running, so it fits an `if` or a `while` (*Did It Work? Exit Codes, && and ||*).
- **Waiting five seconds:** a loop that runs `sleep 1` and then checks, five times at most, stopping as soon as the process is gone.
- **The PID of the export:** `$!` is the PID of the job you started last with `&` (*Background Jobs: &, jobs, fg and bg*).
- **Surviving the terminal closing:** `nohup` goes in front of the command, and `> export.log 2>&1` sends its output and its errors into the log.

## When you're done

Every check passes:

```text
check.bats
 ✓ the scripts and the mess are here
 ✓ 1) the program using the most CPU
 ✓ 2) the polite way to stop process 4242
 ✓ 3) one command for every alarm.sh
 ✓ 4) the signal for a program that ignores TERM
 ✓ 5) the signal Ctrl+C sends
 ✓ 6) stop-politely.sh with no PID shows how to use it
 ✓ 7) stop-politely.sh says when there's no such process
 ✓ 8) stop-politely.sh stops a process with TERM
 ✓ 9) stop-politely.sh sends KILL only after TERM and a wait
 ✓ 10) start-export.sh returns at once and saves the PID
 ✓ 11) the export keeps running after a hang-up
 ✓ 12) the export's output goes to export.log

13 tests, 0 failures
```

Now look back at `stop-politely.sh`. Your export saves its PID in `export.pid`; which one line would stop the export politely, using that file and your new tool?

## Submit your exercise

The exercise is how you finish this lesson. When your work is done, put it on GitHub in a repo of your own, then submit that repo's address here.

1. On GitHub, click **+**, then **New repository**. Name it (for example `exercise-bash-stop-the-runaway`), choose **Public**, and click **Create repository**. Leave out the README: your folder already has one.
2. In a terminal in your exercise folder (Ubuntu in WSL on Windows), send your work to your new repo. If you downloaded the ZIP:

   ```bash
   git init -b main
   git add .
   git commit -m "My solution"
   git remote add origin https://github.com/your-name/exercise-bash-stop-the-runaway.git
   git push -u origin main
   ```

   If you cloned the starter instead, point your copy at your own repo, then commit and push:

   ```bash
   git remote set-url origin https://github.com/your-name/exercise-bash-stop-the-runaway.git
   git add .
   git commit -m "My solution"
   git push -u origin main
   ```

3. Paste your repo's address, such as `https://github.com/your-name/exercise-bash-stop-the-runaway`, into **Submit your exercise** on this page. The site checks that the repo is public and holds your commits, and then the lesson is complete.

Changed something after you submitted? Push it, and submit again: your latest submission is the one that counts.

## So what

Finding what's running, stopping it politely before you use force, and starting a long job so it outlives your terminal is the everyday care of any computer, from your laptop to a server you'll never see.

## Key terms

- [Process](https://www.ask-codey.com/glossary/process)
- [Process ID (PID)](https://www.ask-codey.com/glossary/process-id-pid)
- [kill](https://www.ask-codey.com/glossary/kill)
- [Signal](https://www.ask-codey.com/glossary/signal-unix)
- [nohup](https://www.ask-codey.com/glossary/nohup)

## Related

- [What's Running: ps, top and htop](https://www.ask-codey.com/lessons/bash-processes)
- [Stopping Things: kill and Signals](https://www.ask-codey.com/lessons/bash-kill-and-signals)
- [Background Jobs: &, jobs, fg and bg](https://www.ask-codey.com/lessons/bash-background-jobs)

Source: https://www.ask-codey.com/lessons/exercise-bash-stop-the-runaway
