while / until
while repeats a loop as long as a command's exit status is true (0). until is the opposite — it repeats while the condition is false. Both are commonly used to read a file line by line.
Syntax
Repeat with a while loop.
while condition; do
commands
done
Repeat with an until loop (repeats while the condition is false).
until condition; do
commands
done
Read a file line by line.
while IFS= read -r line; do
commands
done < filename
Read from a pipe (runs in a subshell — be aware of variable scope).
command | while IFS= read -r line; do
commands
done
Infinite loop.
while true; do
commands
done
Syntax Patterns
| Pattern | Description |
|---|---|
| while [ condition ] | Repeats the loop while the condition is true. |
| while (( condition )) | Repeats while the arithmetic condition is non-zero. |
| until [ condition ] | Repeats the loop while the condition is false. |
| while true | Loops indefinitely until an explicit break exits the loop. |
| while IFS= read -r line | Safely reads a file one line at a time. |
| break | Exits the loop immediately. |
| continue | Skips the rest of the current iteration. |
Sample Code
A basic while loop that counts from 1 to 5.
while_count.sh
#!/bin/bash
count=1
while [ $count -le 5 ]; do
echo "Count: $count"
(( count++ ))
done
bash while_count.sh
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
You can also type a while loop directly in the terminal. After pressing Enter following do, a > prompt appears indicating more input is expected. Type done to execute.
count=1; while [ $count -le 5 ]; do
echo "Count: $count"
(( count++ ))
done
Count: 1
Count: 2
Count: 3
Count: 4
Count: 5
until loops while the condition is false — the opposite behavior of while.
until_count.sh
n=0
until [ $n -ge 5 ]; do
echo "n = $n"
(( n++ ))
done
bash until_count.sh
n = 0
n = 1
n = 2
n = 3
n = 4
The standard pattern for reading a file line by line. IFS= preserves leading and trailing whitespace, and -r prevents backslash interpretation.
read_lines.sh
while IFS= read -r line; do
echo "Line: $line"
done < /etc/hosts
bash read_lines.sh
Line: 127.0.0.1 localhost
Line: 255.255.255.255 broadcasthost
Line: ::1 localhost
An infinite loop is useful for process monitoring. Use break to exit explicitly.
monitor.sh
while true; do
if ! pgrep -x "myapp" > /dev/null; then
echo "myapp is not running. Restarting..."
./myapp &
fi
sleep 60
done
Split CSV fields by changing IFS to a comma.
csv_parse.sh
while IFS=',' read -r name score grade; do
echo "Name: $name, Score: $score, Grade: $grade"
done <<'EOF'
Alice,95,A
Bob,78,C
Charlie,88,B
EOF
bash csv_parse.sh
Name: Alice, Score: 95, Grade: A
Name: Bob, Score: 78, Grade: C
Name: Charlie, Score: 88, Grade: B
Process the output of a command one line at a time using a pipe.
find_lines.sh
find . -name "*.php" | while IFS= read -r file; do
lines=$(wc -l < "$file")
echo "$file: $lines lines"
done
bash find_lines.sh
./index.php: 120 lines
./ajax.php: 85 lines
Notes
When processing a file line by line, while IFS= read -r line; do ... done < file is the standard pattern. Without IFS=, leading and trailing whitespace is stripped from each line. Without -r, backslashes are interpreted and expanded.
A while loop fed by a pipe runs in a subshell. This means any variables updated inside the loop are not accessible in the outer shell after the loop ends. To share variables, use process substitution (< <(command)) or a temporary file instead.
For iterating over a list, for is usually a better fit.
If you find any errors or copyright issues, please contact us.