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 breakcommand 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.

Leave a Reply

Your email address will not be published. Required fields are marked *