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. until
Both 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 bash
for
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 bash
To 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 bash
while
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 bash
In 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 bash
For 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 bash
until
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