The short answer
In Bash, the while statement is a control structure used to repeat a set of instructions for as long as a specified condition remains true.
To declare a while loop, you can use the following syntax:
while [condition];
do
# instructions
done
Run in Warp
Where:
- condition is an expression used to keep the loop running for as long as it evaluates to true.
- do and done are used to delimit the instructions executed by the while loop.
- instructions is a list of one or more commands that will be executed by the while loop.
For example, let's consider this script used to print every digit from 1 to 9:
#!/bin/bash
x=1
while [ $x -le 9 ];
do
echo $x
(( x++ ))
done
Run in Warp
Where:
- $x -le 9 is used to evaluate whether the x variable is lesser than or equal to 9.
- echo $x is used to output the value of the x variable.
- (( x++ )) is used to increment the value of the x variable by 1 at each loop iteration.
Terminating the loop with the break
statement
The break statement is used to immediately terminate the current loop, regardless of whether the loop's condition evaluates or not to false.
For example, let's consider this script that determines whether a number is prime:
#!/bin/bash
is_prime=true
number=3
i=2
while [ $i -lt $number ];
do
if [[ $number -le 1 || $(($number % $i)) -eq 0 ]]; then
is_prime=false
break
fi
((i++))
done
echo $is_prime
Run in Warp
Where:
- $i -lt $number checks whether the i variable is lesser than the number variable.
- $number -le 1 checks whether the number variable is lesser than or equal to 1.
- $(($number % $i)) -eq 0 checks whether the number variable is divisible by the i variable.
- break immediately terminates the while loop if either one of the conditions above are true.
Skipping a loop iteration with the continue
statement
The continue statement is used to skip the current iteration of a loop and directly proceed to the next iteration, without executing the remaining instructions.
For example, let's consider this script that prints all the numbers between 1 and 15 that are divisible by 3:
#!/bin/bash
number=1
max=15
while [ $number -le $max ];
do
if [ $((number % 3)) -ne 0 ]; then
((number++))
continue
fi
echo "$number"
((number++))
done
Run in Warp
Where:
- $number -le $max checks if the number variable is lesser than or equal to the max variable.
- $((number % 3)) -ne 0 checks if the number variable is divisible by 3.
- ((number++)) increments the number variable by 1.
- continue skips the remaining instructions and immediately starts a new loop iteration from the beginning.
Reading from a file line by line
To read and process a text file line by line, you can combine the while loop with the read command as follows:
#!/bin/bash
file="/path/to/file"
while read -r line
do
# instructions
done < "$file"
Run in Warp
Where:
- The file variable is used to store the absolute or relative path to the file.
- The read -r command is used to read the file line by line.
- The line variable is used to store the current line returned by the read command.
- The < operator is used to specify the source the read command should read its input from.
For example, this script reads each line of the "/var/log/apache2/access.log" file and only output the lines that contain the 192.168.2.101 IP address:
#!/bin/bash
log_file="/var/log/apache2/access.log"
ip_address="192.168.2.101"
while IFS= read -r line
do
if [[ $line == *"$ip_address"* ]]; then
echo "$line"
fi
done < "$log_file"
Run in Warp
Reading from the standard input
To read and process text from the standard input, you can combine the while loop with the read command as follows:
bash
#!/bin/bash
while true;
do
read input
done
Run in Warp
Where:
- input is a variable that stores the input captured by the read command.
For example, let's consider this script that makes a player enter a number and a second player guess that number:
#!/bin/bash
tries=0
read -p "Please enter a number: " number
echo "Got it! Clearing the screen in 3 seconds..."
sleep 3
clear
while true;
do
read -p "Guess the number: " guess
if [[ number -eq guess ]]; then
echo "Great job! You guess in $tries tries."
break
else
echo "Wrong number. Try again..."
((tries++))
fi
done
Run in Warp
Where:
- read -p prompts the user with a string and reads its input.
- sleep pauses the execution of the program for a certain amount of seconds.
- clear clears all the text from the terminal window.
Iterating on array elements
To iterate over the elements of an array, you can initialize an index variable to zero and use the loop condition to check if the index is less than the array's length, incrementing the index within the loop to access and process each element sequentially.
#!/bin/bash
array=(element1, ..., elementN)
index=0
while [ $index -lt ${#array[@]} ];
do
# do something with element: ${array[$index]}
((index++))
done
Run in Warp
Where:
- element1, …, elementN are a list of comma-separated array values, such as strings or numbers.
- index is a positional index used to access the current array element.
- ${#array[@]} is used to get the number of elements (i.e. the length) of the array.
- ${array[$index]} is used to access the value specified at index.
- ((index++)) is used to increment the index value by one.
For example, let's consider this script that outputs all the files in the current directory with a .js file extension:
#!/bin/bash
files=($(ls))
index=0
while [ $index -lt ${#files[@]} ];
do
if [[ ${files[$index]} =~ .js$ ]]; then
echo "${files[$index]}"
fi
((index++))
done
Run in Warp
Where:
- ($(ls)) is used to declare the list of files returned by the ls command as an array of strings.
- ${files[$index]} =~ .js$ checks if the current filename ends with the string ".js".
Creating an infinite while
loop
To create an infinite while loop in Bash, you must define a condition that never evaluates to false.
The most common way of doing so is to use the built-in true value as follows:
#!/bin/bash
while true;
do
# instructions
done
Run in Warp
Alternatively, you can also use a semicolon character (:) as follows:
bash
#!/bin/bash
while :
do
# instructions
done
Run in Warp
For example, let's consider this script that simply "echoes" back into the terminal the user input until it reads the "exit" string:
#!/bin/bash
echo "Enter text (type 'exit' to quit):"
while true;
do
read -p "> " input
if [ "$input" == "exit" ]; then
echo "Goodbye!"
break
fi
echo "You entered: $input"
done
Run in Warp
Written by
Winnie Ondara
Filed Under
Related Articles
Bash If Statement
Learn how to use the if statement in Bash to compare multiple values and expressions.
POST JSON Data With Curl
How to send valid HTTP POST requests with JSON data payloads using the curl command and how to avoid common syntax pitfalls. Also, how to solve the HTTP 405 error code.
Use Cookies With cURL
Learn how to store and send cookies using files, hard-coded values, environment variables with cURL.
Loop Through Files in Directory in Bash
Learn how to iterate over files in a directory linearly and recursively using Bash and Python.
How To Use sudo su
A quick overview of using sudo su
Generate, Sign, and View a CSR With OpenSSL
Learn how to generate, self-sign, and verify certificate signing requests with `openssl`.
How to use sudo rm -rf safely
We'll help you understand its components
How to run chmod recursively
Using -R is probably not what you want
Run Bash Shell In Docker
Start an interactive shell in Docker container
Curl Post Request
Use cURL to send data to a server
Reading User Input
Via command line arguments and prompting users for input
Bash Aliases
Create an alias for common commands