Bash While Loops: From Basics to Real-world Applications
In Bash scripting, a while loop is used to execute a block of statements as long as a specified condition is true. The basic syntax is:
while [CONDITION] do # Commands to be executed done
The loop will continue to execute as long as the CONDITION evaluates to true. When the condition becomes false, the loop terminates, and the program continues with the next statement following the loop.
Simple While Loop Example
Let’s see a basic example of the while loop:
count=1 while [ $count -le 5 ] do echo "This is loop number $count" ((count++)) done
Output:
This is loop number 1 This is loop number 2 This is loop number 3 This is loop number 4 This is loop number 5
Here, a variable count
is initialized to 1. The loop will continue executing as long as the value of count
is less than or equal to 5.
Inside the loop, the value of count
is incremented by 1 in each iteration using ((count++))
, and a message is printed to the screen.
Looping Through Files
You can use a while loop to iterate through files.
You can process all text files in a directory to read them like this:
find . -name "*.txt" | while read file do echo "Processing $file" # You can add commands here to process each file done
Output:
Processing ./file1.txt Processing ./file2.txt Processing ./directory/file3.txt
In this example, the find
command lists all the .txt
files in the current directory and its subdirectories.
The while
loop reads each line (file path) and executes the code within the loop for each file.
Here, it prints a message, but you could add any commands to process each file as needed.
Using the test Command with While Loops
The test
command in Bash is used to check file types and compare values. It’s commonly used within a while loop to provide more complex condition checking.
You can use the test command to check file size:
file_size=$(stat -c%s "file.txt") while [ $file_size -lt 1024 ] do echo "File size is $file_size bytes. Waiting to reach 1KB..." sleep 1 file_size=$(stat -c%s "file.txt") done
Output:
File size is 100 bytes. Waiting to reach 1KB... File size is 500 bytes. Waiting to reach 1KB... ...
In this example, you first determine the file size of “file.txt” using stat -c%s
. The while loop continues to execute as long as the file size is less than 1024 bytes (1KB).
Inside the loop, a message is printed, and then the script waits for 1 second before checking the file size again.
This loop will continue until the file size reaches or exceeds 1KB.
Conditions within while loops allow for various comparisons. Here’s how you can perform them.
Numeric Comparison
value=10 while [ $value -ne 0 ] do echo "Value is $value" ((value--)) done
Output:
Value is 10 Value is 9 ... Value is 1
You use -ne
to continue the loop as long as the value is not equal to 0. The value decreases by 1 in each iteration.
String Comparison
name="John" while [ "$name" != "Doe" ] do echo "Name is $name" name="Doe" # You would update this from an external source done
Output:
Name is John
You use !=
to compare strings and continue the loop as long as name
is not equal to “Doe.”
File Testing within the Loop
while [ ! -e "file.txt" ] do echo "Waiting for file.txt to be created..." sleep 1 done
Output:
Waiting for file.txt to be created...
You use -e
to check the existence of a file and continue looping until “file.txt” exists.
Exiting the Loop
The break
command enables you to exit a loop before the condition becomes false.
count=1 while [ $count -le 10 ] do if [ $count -eq 5 ]; then break fi echo "Count: $count" ((count++)) done
Output:
Count: 1 Count: 2 Count: 3 Count: 4
In this snippet, the loop would normally iterate until count
reaches 10. However, when count
equals 5, the break
command is executed, terminating the loop early.
Skip to the Next Iteration
The continue
command is used to skip the current iteration of a loop and continue with the next iteration.
number=1 while [ $number -le 10 ] do if [ $((number % 2)) -eq 0 ]; then ((number++)) continue fi echo "Odd number: $number" ((number++)) done
Output:
Odd number: 1 Odd number: 3 Odd number: 5 Odd number: 7 Odd number: 9
Here, the loop iterates through the numbers from 1 to 10, but the continue
command skips the even numbers, causing the loop to print only the odd numbers.
Infinite Loops
An infinite loop can be created with the following syntax:
while true do echo "This will run forever." done
Infinite loops can be controlled by implementing an exit strategy.
count=1 while true do echo "Loop $count" ((count++)) if [ $count -gt 5 ]; then break fi done
Output:
Loop 1 Loop 2 Loop 3 Loop 4 Loop 5
The while
loop is always true, but we used the break
command to exit the while loop when the count reaches 5, thus preventing an actual infinite loop.
Nested While Loops
A nested while loop is a loop within another loop. Here’s an example of how you can use them:
i=1 while [ $i -le 10 ] do j=1 while [ $j -le 10 ] do echo -n "$((i * j)) " ((j++)) done echo "" ((i++)) done
Output:
1 2 3 ... 10 2 4 6 ... 20 ... 10 20 30 ... 100
Here, the outer loop iterates over the numbers 1 through 10, and the inner loop also iterates over the numbers 1 through 10.
The multiplication of i
and j
is printed.
Utilizing Input within While Loops
You can use while loops to process input from files or users.
Reading Lines from a File
while read line do echo "Line: $line" done < file.txt
Output:
Line: First line of file.txt Line: Second line of file.txt ...
Here, the read
command reads each line from “file.txt”, and the loop processes each line individually.
Reading User Input
while true do read -p "Enter 'exit' to quit: " input if [ "$input" == "exit" ]; then break fi echo "You entered: $input" done
Output (depends on user input):
Enter 'exit' to quit: hello You entered: hello Enter 'exit' to quit: exit
This snippet reads user input until the user enters “exit”, it will call the break
command to exit the loop.
Error Handling in While Loops
Using undefined variables or incorrect command syntax can lead to errors. You should consider these errors.
file="file.txt" while read line do # Processing code here done < "$file" || echo "Error reading $file"
Here, if reading the file fails, an error message is printed.
Debugging Techniques (using set -x)
To trace a script’s execution, you can use the set
command.
set -x count=1 while [ $count -le 5 ] do echo $count ((count++)) done set +x
Output:
+ count=1 + '[' 1 -le 5 ']' + echo 1 1 + (( count++ )) + '[' 2 -le 5 ']' + echo 2 2 ...
The set -x
command prints each command and its expanded arguments before it’s executed, providing a detailed trace of what’s happening within the loop.
Real-world Applications
While loops are vital in real-world applications for automating and monitoring tasks.
Monitoring System Resources
while true do free -m | awk '/^Mem:/ {print "Free memory: " $4 " MB"}' sleep 5 done
This example prints the free memory every 5 seconds, utilizing the free
and awk
commands.
Automating Repetitive Tasks
files="/path/to/files/*.txt" while read file do gzip "$file" done <<< "$(ls $files)"
Here, the loop compresses all the text files in a directory using the gzip
command.
These examples illustrate some applications of while loops in system monitoring and task automation.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.