Skip to content
Linux Basics: Repeat Work with Bash Loops

Linux Basics: Repeat Work with Bash Loops

October 18, 2026

Loops repeat a small block of commands. Beyond greeting a list of arguments, common jobs include bounded calculations, reading complete lines, and stopping when a condition is met.

These examples were tested on Linux with GNU Bash 5.2.37. Use Bash rather than sh; some syntax is Bash-specific. No packages or administrator access are needed.

Prepare a scratch directory

You need Bash, a text editor, and the mktemp, rm, and rmdir utilities. Keep using the same terminal. The guards stop the shell if setup fails. Save each named source file in this directory before running its command. Calling bash explicitly means you do not need to change executable permissions.

start_dir="$PWD"
work_dir="$(mktemp -d)" || exit 1
cd -- "$work_dir" || exit 1

1. Repeat a bounded calculation

Save this as loop-count.sh:

#!/usr/bin/env bash
total=0
for (( number=1; number<=4; number++ )); do
  total=$((total + number))
  printf 'After %s: %s\n' "$number" "$total"
done

Run it:

bash loop-count.sh

Output:

After 1: 1
After 2: 3
After 3: 6
After 4: 10

The arithmetic for form has an initializer, a condition, and an update. It checks the condition before each iteration. A clear bound makes this useful for small, known counts without starting an external sequence command.

2. Read lines without losing spaces

Save this as loop-lines.sh:

#!/usr/bin/env bash
printf '  first item  \nsecond\\item' > lines.txt
count=0
while IFS= read -r line || [[ -n "$line" ]]; do
  count=$((count + 1))
  printf '%s: <%s>\n' "$count" "$line"
done < lines.txt
printf 'Lines: %s\n' "$count"

Run it:

bash loop-lines.sh

Output:

1: <  first item  >
2: <second\item>
Lines: 2

IFS= preserves leading and trailing whitespace. read -r keeps backslashes literal. The extra condition processes the last nonempty line even without a final newline. Redirecting a file into the loop keeps its counter in the current shell; a pipeline can put the loop in a subshell. This script creates only lines.txt in the scratch directory.

3. Skip an item and stop early

Save this as loop-control.sh:

#!/usr/bin/env bash
for item in draft skip ready stop later; do
  if [[ "$item" == skip ]]; then
    continue
  fi
  if [[ "$item" == stop ]]; then
    break
  fi
  printf 'Process: %s\n' "$item"
done
printf 'Loop finished\n'

Run it:

bash loop-control.sh

Output:

Process: draft
Process: ready
Loop finished

continue skips the rest of the current iteration. break exits the loop, so later is never visited. Both affect the innermost loop by default. Keep the stopping rule visible to avoid accidental unbounded work.

Clean up

In the same terminal, remove only the example files, return to your original directory, and remove the empty scratch directory:

rm -- loop-count.sh loop-lines.sh loop-control.sh lines.txt
cd -- "$start_dir" || exit 1
rmdir -- "$work_dir"
unset start_dir work_dir

Reference

The GNU Bash manual: Looping Constructs documents the syntax used here.

Acknowledgements

This post was created with assistance from AI.

Last updated on