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.
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
# Ten przykład pokazuje, jak `read` używa domyślnego IFS do przycinania spacji
# oraz jak -d zmienia separator wejścia.
echo " First Second, Third Fourth ," | while read -r -d, word; do
echo "=$word="
done
# Wynik:
# =First Second=
# =Third Fourth=
W tym przypadku opcja -d, mówi read, aby zakończył czytanie na przecinku (,). Następnie read używa **domyślnego `IFS`** do usunięcia wiodących i końcowych spacji z każdego segmentu. Ważne jest, że read **nie dzieli** ciągu na słowa wewnątrz segmentu; jedynie go przycina.
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.