Last updated on February 13, 2021 by Dan Nanni
Undoubtedly the most useful feature of bash scripting is loop control. In any imperative programming language like bash, loop statements are commonly used along with conditional statements to perform repetitive tasks. In case of bash, three different types of loop statements are available: for, while and until. Each of these loop statements comes in handy in slightly different circumstances.
In this tutorial, I explain how to use for, while and until loops in bash shell scripts, and demonstrate their use cases using shell script examples.
for vs. while vs. untilBoth the for and while statements allow you to express a loop with a terminating condition (i.e., run the loop while the condition is true). The for statement is more versatile than the while statement as you can also iterate over a list of items using a for loop without explicitly defining a condition. Thus for loops are often used when the number of loop iterations or the items to iterate over are already known.
Similar to for and while, the until statement allows you to define a conditional loop. However, the difference of until lies in how the condition is handled. The for/while loops are executed while the condition is true. On the other hand, until loops are iterated until the condition is true, meaning that the loops are executed while the condition is false.
With these key differences in mind, let's go over the syntax and examples of for, while and until loops in the following.
for Loops in bashfor Loop SyntaxThe most commonly used form of for loops is a single-expression loop as shown below. The loop body surrounded by do and done is executed as long as <conditional-expression> evaluates to true. <conditional-expression> can be written in many different forms, some of which will be illustrated with examples later.
for <conditional-expression>
do
<loop-body>
done
for <conditional-expression>; do
<loop-body>
done
Another form of for loops is a three-expression loop as shown below. The control flow in this loop is as follows. First, <init-expression> is executed once before the loop starts. Then <conditional-expression> is evaluated. If the condition evaluates to true, the loop is entered and the loop body is executed. After the loop body is completed, the control flow jumps back to <update-expression>, where any loop control variable can be updated. Then <conditional-expression> is evaluated again. If true, loop iteration continues, and the whole process repeats itself.
Note that there should be spaces between opening/closing double round brackets and the init/update expressions.
for (( <init-expression>; <conditional-expression>; <update-expression> )); do
<loop-body>
done
for Loop in bashTo repeat N times, where N is a variable, use either of the following formats.
N=10 for i in $(seq 1 $N); do echo "$i-th run" done
N=10
for (( i=0; i <= $N ; i++ )); do
echo "$i-th run"
done
To iterate over a fixed range of values, specify the range with {START..END} in the conditional expression.
# iterate all integers from 10 to 100
for i in {10..100}; do
echo "count $i"
done
To iterate over a range of values with a fixed increment, use {START..END..INCREMENT} in the conditional expression.
# iterate over 10, 15, 20, ..., 95, 100
for i in {10..100..5}; do
echo "count $i"
done
The above for loop can of course be re-written easily with a three-expression loop.
for (( i=0; i <= 100 ; i=i+5 )); do
echo "count $i"
done
for Loop in bash
fruit_list=('apple' 'orange' 'kiwi' 'pear' 'watermelon')
for fruit in "${fruit_list[@]}"; do
echo $fruit
done
fruit_list="apple orange kiwi pear watermelon"
for fruit in $fruit_list; do
echo $fruit
done
for fruit in apple orange kiwi pear watermelon; do
echo $fruit
done
while Loop in bashwhile Loop SyntaxA while loop in bash consists of a conditional expression and a loop body which is surrounded by do and done. The loop body continues to be executed as long as the condition evaluates to true. The conditional expression in while loop can be surrounded by either a pair of single square brackets or a pair of double round brackets. Depending on whether you are using square brackets or round brackets, the type of operators you are allowed to use vary, as illustrated below. Also note that there should be spaces between opening/closing brackets and the conditional-expression.
while [ <conditional-expression> ]; do
<loop-body>
done
while (( <conditional-expression> )); do
<loop-body>
done
while Loop in bashIn a while loop, integer comparison inside the square brackets should be expressed using bash's built-in comparison operators (-eq for "equal to", -ne for "not equal to", -gt for "greater than", -ge for "greater than or equal to", -lt for "less than", -le for "less than or equal to").
i=0
while [ $i -lt 100 ]; do
i=`expr $i + 1`
echo $i
done
If you are using double round brackets, you can use '>', '<', '==', '!=', '>=', '<=' operators for integer comparison in while loop.
i=0
while (( $i < 100 )); do
i=`expr $i + 1`
echo $i
done
while Loop in bashFor string comparison (equal or not equal), you can use regular comparison operators ('==', '!='), whether you are using square brackets or double round brackets. The '=' operator can also be used to check equality of strings.
TIME=`date +%H:%I`
while [ "$TIME" != "00:00" ]; do
# do something
HOUR=`date +%H:%I`
done
TIME=`date +%H:%I`
while (( "$TIME" == "00:00" )); do
# do something
HOUR=`date +%H:%I`
done
while (( "$TIME" = "00:00" )); do
# do something
HOUR=`date +%H:%I`
done
while LoopWhen you want to specify multiple conditions with logical AND/OR, you can do that in several different ways.
Combine multiple pairs of square brackets using '&&', '||' operators:
MIN=`date +%M`
while [ "$MIN" -gt 0 ] && [ "$MIN" -lt 30 ] ; do
# do something
MIN=`date +%M`
done
Use a single pair of square brackets and use bash's built-in logical operators (-a for AND, -o for OR):
MIN=`date +%M`
while [ "$MIN" -gt 0 -a "$MIN" -lt 30 ] ; do
# do something
MIN=`date +%M`
done
Use a single pair of double round brackets and use '&&' and '||' operators.
MIN=`date +%M`
while (( "$MIN" > 0 && "$MIN" < 30 )); do
# do something
MIN=`date +%M`
done
until Loop in bashuntil Loop SyntaxThe syntax of until loops is identical to that of while loops. But contrary to while loops, the loop body in until loops continues to be executed only if <conditional-expression> evaluates to false. As soon as <conditional-expression> evaluates to true, the loop is exited.
Similar to while loops, the conditional expression in until loops can be surrounded by either a pair of single square brackets or a pair of double round brackets. The type of comparison operators you are allowed to use inside the brackets vary depending on whether you are using square brackets or round brackets. There should be spaces between opening/closing brackets and the conditional-expression.
until [ <conditional-expression> ]; do
<loop-body>
done
until (( <conditional-expression> )); do
<loop-body>
done
The semantic difference between while and until can be illustrated with the following two shell scripts. They produce exactly the same result.
i=0
while [ $i -lt 100 ]; do
i=`expr $i + 1`
echo $i
done
i=0
until [ $i -ge 100 ]; do
i=`expr $i + 1`
echo $i
done
For other until loop examples such as integer comparison, string comparison and multiple conditions, refer to those demonstrated in the while loop.
bash shell scripting tutorials provided by Xmodulo.This website is made possible by minimal ads and your gracious donation via PayPal or credit card
Please note that this article is published by Xmodulo.com under a Creative Commons Attribution-ShareAlike 3.0 Unported License. If you would like to use the whole or any part of this article, you need to cite this web page at Xmodulo.com as the original source.
Xmodulo © 2021 ‒ About ‒ Write for Us ‒ Feed ‒ Powered by DigitalOcean