Bash: While Loop
A `while` loop executes a set of commands as long as its condition remains true. It's ideal for loops with an unknown number of iterations.
General Syntax
while command_list; do
body
done
The while loop executes the command_list and checks its exit code. If the exit code is 0 (success), the loop's body is executed, and the process repeats. If the exit code is any other number (failure), the loop terminates. This fundamental behavior is why commands like [ ] or read are used as loop conditions.
Looping while a condition is true
counter=0
while [ $counter -lt 5 ]; do
echo "The counter is $counter"
counter=$((counter+1))
done
A `while` loop continues to execute as long as its conditional expression remains true. The `-lt` operator means "less than." This is a useful loop for reading files line by line, as seen in the "Reading Files" cheatsheet.
When to use square brackets [ ] vs. a command
The condition in a while loop is based on the exit code of a command.
- Use square brackets
[ ](which is a shortcut for thetestcommand) for testing conditions like numeric comparisons (`-lt`, `-eq`), string comparisons (`==`), or file checks (`-f`, `-d`). The command returns0(success) if the condition is true, and1(failure) if it's false. - Do not use brackets when the condition is a simple command whose own exit code determines the loop's continuation. For example, the
readcommand returns a successful exit code (0) as long as it successfully reads a line. When it reaches the end of the file, it returns a non-zero exit code, terminating the loop.
Infinite while loop
while true; do
echo "This will run forever"
done
An infinite while loop continues to execute indefinitely because the condition true always evaluates to success. Use this pattern with caution and ensure there is a break condition or an external mechanism to terminate the loop.
Example with a command
while read line; do
echo "$line"
done < file.txt
In this example, the loop continues as long as the read command is successful. By default, read uses the newline character as its delimiter, ensuring it reads a full line at a time. This is a common and efficient pattern for processing file contents line by line.
Iterating over a string or list
You can use a while loop to iterate over strings or lists by combining it with the read command and a here string (<<<) or a pipeline. This is a common pattern for processing data without using a file.
Iterating over a string (word by word) and `read` subtleties
# That examples presents how the `read` command processes input
# and how the `-d` option changes the input delimiter.
echo " First Second, Third Fourth ," | while read -r -d, word; do
echo "=$word="
done
# Result:
# =First Second=
# =Third Fourth=
In this case, the -d, option tells read to stop reading at a comma (,). Then read uses the default `IFS` to remove leading and trailing spaces from each segment. It's important to note that read does not split the string into words within a segment; it only trims it.
Iterating over a list (line by line)
list="first_item
second_item
third_item"
while read item; do
echo "Processing: $item"
done <<< "$list"
Here, a here string (<<<) is used to provide the multi-line string to the loop. read processes it line by line because the newline is the default delimiter.