keepcalculator

06 Numbers and Powers

Bash while loop tutorial and examples

Card No. 06·20380 · Updated · Standard formula, shown below

Loop iterations executed 5
Number of iterations
5
You entered
You enter
Number of iterations
You get
Loop iterations executed
Rounding
0 dp

This article explains how to use the Bash while loop, a control structure that repeats a block of commands as long as a given condition is true. You will learn the syntax, see practical examples for reading files, iterating over numbers, and building menus, and understand common pitfalls like infinite loops and off-by-one errors.

What is a Bash while loop?

A while loop in Bash is a programming construct that executes a list of commands repeatedly as long as a given condition evaluates to true. The condition is tested before each iteration, so if it is false at the start, the loop body never runs. This makes while ideal for situations where you don’t know in advance how many times you need to iterate, such as reading lines from a file until the end, waiting for a process to finish, or monitoring a system resource.

Basic syntax and structure

The general syntax is:

while [ condition ]
do
    # commands to run
    # update the condition or counter
done

You can also write it on a single line with semicolons:

while [ condition ]; do commands; done

Key points:

  • The condition is usually a test command inside square brackets [ ... ] or double brackets [[ ... ]] (Bash-specific).
  • The do and done keywords mark the start and end of the loop body.
  • If the condition is true, the body runs; then the condition is checked again. This repeats until the condition becomes false.
  • You can use break to exit the loop early and continue to skip the rest of the current iteration and jump to the next one.

Practical examples

1. Counting loop with a counter

The most common use is a counter that increments each iteration:

#!/bin/bash
counter=1
while [ $counter -le 5 ]
do
    echo "Iteration $counter"
    ((counter++))
done

This prints Iteration 1 through Iteration 5. The condition $counter -le 5 is true as long as the counter is less than or equal to 5. The line ((counter++)) increments the counter by 1.

2. Reading a file line by line

The canonical way to process a file line by line is:

#!/bin/bash
while IFS= read -r line
do
    echo "Line: $line"
done < input.txt

Here IFS= preserves leading/trailing whitespace, and -r prevents backslash escapes from being interpreted. The file input.txt is redirected as input to the entire loop. This pattern is safe even for files without a trailing newline.

3. Infinite loop with break

Sometimes you want a loop that runs until a certain condition is met inside the body:

#!/bin/bash
while true
do
    read -p "Enter a number (0 to quit): " num
    if [ "$num" -eq 0 ]; then
        break
    fi
    echo "You entered $num"
done

while true creates an infinite loop; the break statement exits it when the user enters 0.

4. Using arithmetic conditions

For numeric comparisons, you can use double parentheses (( )) directly:

#!/bin/bash
n=10
while (( n > 0 ))
do
    echo "$n"
    ((n--))
done

This prints numbers from 10 down to 1.

Common pitfalls and how to avoid them

  • Infinite loops: Forgetting to update the condition or counter. Always ensure that the condition eventually becomes false, or include a break.
  • Off-by-one errors: Using -lt instead of -le (or vice versa) can cause one extra or one fewer iteration. Test with a small number.
  • Spacing in [ ]: The brackets must have spaces around them: [ $i -lt 5 ] is correct, [$i -lt 5] is not.
  • Variable quoting: Always quote variables in test conditions to avoid word splitting and globbing: [ "$var" = "yes" ].
  • Changing IFS: If you modify IFS inside a loop, it can affect other parts of the script. Save and restore it if needed.

Choosing between while, for, and until

Bash offers three main loop types:

  • for: Best when you know the number of iterations or have a list of items (e.g., files, command output).
  • while: Best when you want to repeat until a condition becomes false, especially when the number of iterations is unknown (e.g., reading a stream).
  • until: The opposite of while – it loops as long as the condition is false. It’s less common but useful for waiting for a condition to become true.

For example, to iterate over all .txt files, a for loop is more natural:

for file in *.txt; do echo "$file"; done

But to read lines from a command output, while is preferred:

command | while read line; do echo "$line"; done

Performance and best practices

While loops in Bash are generally slower than equivalent awk or sed commands for heavy text processing, because each iteration forks a subprocess. For large files, consider using awk or sed instead. However, for scripting tasks that involve logic, while is perfectly fine.

Best practices:

  • Always test your loop with a small input or a counter limit before running it on real data.
  • Use set -u to catch unset variables and set -e to exit on errors, but be aware that set -e can behave unexpectedly inside loops.
  • Prefer [[ ... ]] over [ ... ] in Bash for more features and fewer surprises (e.g., pattern matching, no word splitting).
  • When reading files, use while IFS= read -r line to preserve content exactly.

Frequently Asked Questions

How do I loop over a range of numbers in Bash?

You can use a C-style for loop: for ((i=1; i<=10; i++)); do echo $i; done. Or use seq: for i in $(seq 1 10); do .... The C-style loop is pure Bash and faster.

How do I break out of a while loop?

Use the break statement. It exits the innermost loop. If you have nested loops and want to break out of an outer loop, you can use break 2 to break out of two levels.

What is the difference between while and until?

while runs as long as the condition is true; until runs as long as it is false. For example, until [ -f file ]; do sleep 1; done waits until a file exists.

Why is my while loop not reading the last line of a file?

If the file does not end with a newline, the read command may not process the final line. Using while IFS= read -r line usually handles this correctly because the loop still runs when the read returns a non-zero exit status but with data. However, some older Bash versions have bugs; a workaround is to append a newline to the file before processing.

Can I use a while loop to read the output of a command?

Yes, you can pipe the command output into a while loop: command | while read line; do ...; done. But note that the loop runs in a subshell, so variables set inside the loop won't be available after the pipeline. To avoid that, use process substitution: while read line; do ...; done < <(command).

How do I run a while loop in the background?

Append an ampersand & to the loop or run the whole script with &. For example: while true; do echo "running"; sleep 1; done &. You can then kill it with the job ID or PID.

Related

Formula used
in n | Number of iterations | - | 5 | 1 | 1000
out loop_count | Loop iterations executed | - | n | 0

Each line is one input (in, sel, list) or one result (out: label, unit, formula, decimals). How the calculators work

Method: the standard formula for this calculation, rounded as each result states. See how the calculators work or report an error.

More cards in this drawer

The whole Numbers and Powers drawer →