Shell Scripting Part 4: Repetition Control Structures
Welcome to part four of HowtoForge's shell scripting tutorial series (Click here to read the part 1, part 2 and part 3 of the tutorial). In this part, we will cover the different repetition control structures of the bash shell and how to use each structure by providing some examples. Let's get started.
Introduction
Repetition control structure, also known as looping control structure, is a type of control structure in programming languages that is used to simplify repetitive or recursive tasks. The looping statements optimize any code by providing a way to minimize code, making it easier to troubleshoot than unstructured code providing the same output. There are three types of looping statements that the bash shell supports - the for, while and until loops.
For Loops
The for loop is a looping statement that uses the keyword for to declare a repetitive statement. The bash supports different syntaxes for the for loop statement:
Syntax 1: For-in Structure
for <varName> in <list>
do
#### your statement here
done
This syntax starts with the keyword for, then followed by a variable name, the keyword in and the list of possible values for the variable. Each value in the list will be separated with a space and the start of the code lines that will be repeated is defined in the do and ends with a done keyword.
Let's create a simple for looping statement that will allow the user to input 5 values and get the sum of the numbers:
#!/bin/bash
result=0;
input=0;
for var in 1 2 3 4 5
do
printf "Input integer %d : " $var
read input
result=$((result+input))
done
echo "the result is " $result
In this example, the variable var serves as the counter of our loop. Its value is defined in the list of numbers after the keyword in and the shell changes the values of the var variable after each execution of the cycle in the looping statement. Since there are only five integer values in our list, shell will execute the codes inside our looping statement for only five times.
Syntax 2: For looping Statement with String list values
You can also declare a variable that will hold for the list of items for your counter. For instance, consider the following code:
#!/bin/bash
list="var1 var2 var3 var4"
var=""
mkdir sample
cd sample
echo creating the "directories...."
for var in $list
do
mkdir $var
done
The line list="var1 var2 var3 var4" defines the values of the list variable. It was then assigned to var in the line for var in $list and finally, the directories are then created in the line mkdir $var.
Syntax 3: For loop statement with list as a file
You can also retrieve a list from an existing file to be used in for looping statement instead of declaring it inside your code by using cat command. For example, open your favourite text editor then list down at least five directory names.
Next open a new tab in the same text editor and create a new script. This script should be saved in the same directory where the list of directories that you previously created is saved.
#!/bin/bash
dirList=$(cat list)
echo "creating directories...."
for var in $dirList
do
mkdir $var
done
This example becomes handy when you have to create hundreds of directory in your Linux computer, don't you think?
Syntax 4: C-like Syntax
for((initialization; boolean_test; increment/decrement))
do
#### your code goes here
done
Perhaps, the most familiar structure of for loop that the shell supports is the C-like structure. The loop starts with the initialization of the counter variable and then the shell evaluates the Boolean expression declared after the initialization. If the Boolean expression result is true, then the shell will execute the set of statements inside the do clause otherwise, it terminates the looping statement and proceeds to line after the done keyword. The shell will proceed to the next iteration through the increment or decrement statement declared after the Boolean test. As an example, let's reconstruct our first example using this structure.
#!/bin/bash
result=0
input=0
for((var=1;var<=5;var++))
do
printf "Input integer %d : " $var
read input
result=$((result+input))
done
echo $result
While Looping Statement
The while statement is a type of repetitive structure in bash that utilizes the keyword while. Unlike the C-type syntax of for looping structure, the while repetitive control structure separates the initialization, Boolean test and the increment/decrement statement.
Syntax 1: While Structure with Arithmetic Symbols based conditional statements
<initialization>
while(condition)
do
###your code goes here
<increment/decrement>
done
To be able to differentiate while from the other looping statements, let's construct our first example for the while statement.
#!/bin/bash
result=0
input=0
var=1
while((var <= 5))
do
printf "Input integer %d : " $var
read input
result=$((result+input))
var=$((var+1))
done
echo "the result is " $result
Looking at our example, the while statement starts with an initialization of our counter variable var. Next, the Boolean test is declared after the keyword while and the set of statements to be repeated will be declared inside the do and done statements. In while statements, the interpreter will only start and execute repetition of codes if the Boolean test result is true. On the other hand, the looping statement will statement will only terminate the iteration of codes when the Boolean expression results to false.
Syntax 2: While Looping Statement with mnemonic based conditional statement
<initialization>
while [ <condition> ]
do
####your code goes here
<increment/decrement>
done
You can also declare mnemonic based conditional statement inside a while loop statement. For declaration, a square bracket will be used instead of parenthesis. (Review the mnemonic based conditional statements here ) For example:
#!/bin/bash
var=1;
while [ $var -le 5 ]
do
printf "Input integer %d : " $var
read input
result=$((result+input))
var=$((var+1))
done
echo "the result is " $result
Syntax 3: While Looping Statement with File-based Conditional Statement
while read <variable_name>
do
####your code goes here
done <<path to the text file>
Just like what we did in the for looping statement, you can also open a text file and associate it in the while looping statement. For example:
#!/bin/bash
mkdir sample2
cd sample2
echo "creating directories..."
while read var
do
mkdir $var
done<list
In this example, I have recycled the list we created a while ago and created a new script in the same directory. Note that if your text file is located on a different directory, you have to provide the exact path of the file after the < symbol.
Until Looping Statement
Another type of looping statement that the bash supports is the until structure. The until statement executes every command inside the loop until the boolean expression declared results to false. It is the complete opposite of the while statement.
Syntax 1: Until Loop with Arithmetic Symbol-based Conditional Statement
until ((<conditional_statement>))
do
####set of commands
done
Let's have an example:
result=0
input=0
var=1
until((var > 5))
do
printf "Input integer %d : " $var
read input
result=$((result+input))
var=$((var+1))
done
echo "the result is " $result
Syntax 2: Until Looping Statement with mnemonic based conditional statement
<initialization>
until [ <condition> ]
do
####your code goes here
<increment/decrement>
done
Since the until statement is just the opposite of while looping statement, you can also declare a mnemonic-based conditional statement in the until structure. However, the in order to terminate the you have to declare an opposite conditional statement - that is, make to conditional statement evaluate to false.
!/bin/bash
result=0
input=0
var=1
until [ $var -gt 5 ]
do
printf "Input integer %d : " $var
read input
result=$((result+input))
var=$((var+1))
done
echo "the result is " $result
Conclusion
This tutorial part covers the three looping structures that the bash supports - the for, while and until looping statement. Each of these statements has different structure, usage and advantages. The bash supports different structures, providing more choices to programmers and thus, making shell scripting easy to code.