Loops are used in computer programming languages to repeat certain instructions several times. This is not only to save time and effort in writing the same instructions again and again but also to prevent human errors that may be introduced during this process.
The same concept of loop is used in Bash scripting to repeat certain commands. A script is a text file used in Linux to write commands that are needed routinely multiple times daily. So, instead of typing these commands again and again you can simply call a script.
In this tutorial, it is assumed that you are already familiar with the basics of scripting in Linux.
Like most programming languages, there are three types of loops that you can use in a Bash script. These are for loop, while loop, and until loop.
This tutorial provides you an insight into the Bash for loop and different ways of using it, along with some examples.
Table of Contents
The Standard Bash for Loop
For loop is used when you know in advance how many times you want to execute a given set of statements/commands.
echo command to demonstrate how the for loop works in most of the examples given below.Basic Syntax
The basic syntax of a for loop in Bash is shown below:
for variable in [LIST]
do
command 1
command 2
command 3
…
done
As you can see, the loop starts with the keyword for, followed by a loop variable name (in this case we’re calling it literally variable) then another keyword in, and lastly a list of elements, all separated by single spaces. All the commands you want to execute multiple times are written inside the do and done keywords pair (called the body of for loop).
The loop variable will take the value of all the members mentioned in the [list], one by one. This means that the loop (and its enclosed commands) will execute the number of times there are members in the list.
The whole structure of this loop can be translated in English as “for each variable mentioned in the list do the following commands”.
You can use multiple things as a list in a for loop (such as numbers, strings, and files, etc.). Eventually, there are many ways in which a for loop can be written in Linux scripts. Let them explore one by one.
Loop Using Numbers
You can write a for loop in Bash script by specifying a list of integer numbers after the keyword in, as shown below.
#! /bin/bash
for i in 1 2 3 4 5
do
echo $i
done
Instead of specifying the starting and ending values and the increment, like in most programming languages, you are only specifying the values the loop variable can take.
In other words, the commands written inside the for loop will execute once for each value in the list. It means that this for loop will execute five times and the echo command would print numbers from 1 to 5 as shown below. (The $ is used before i in the echo command to represent its value, see $i in the above example).
./hello.sh
1 2 3 4 5
Loop Using a Range of Values
What if you want to print the first 200 or 2000 numbers? (In other words, you want to execute a for loop for these numbers of time).
Would you need to write all the numbers from 1 to 200? The answer is NO. You have to specify only the starting and ending number separated by double dots and enclose them in curly braces like this:
#! /bin/bash
for i in {1..200}
do
echo $i
done
You can also specify the increment by another unit, instead of incrementing by 1. For example, you can increment by 2.
To do that, you have to use the double dot again but after the ending value. For example, you want to print only the odd numbers present between 0 to 200. In this case, you will write the for loop as given below:
#! /bin/bash
for i in {1..200..2}
do
echo $i
done
The output is shown below. (To save space, only the odd numbers between 1 to 20 are shown).
./hello.sh
1 3 5 7 9 11 13 15 17 19
Loop Using Strings
Instead of specifying integer numbers, you can also use strings as list members. Suppose you want to print the names of different operating systems. Then, you can write a for loop as shown in the example below.
#! /bin/bash
for os in Windows Mac Android iOS
do
echo "$os"
done
Here, os is the loop variable, which will take different string values specified in the list. You will get the following output upon executing this script.
./hello.sh
Windows Mac Android iOS
The important thing to note is that when you use string members in a list, you have to use double codes in the echo command (see $os is enclosed in double codes).
Loop Over Array Elements
You can also use an array as a list in a for loop. In contrast to a variable that can only hold one value at a time, an array can hold multiple values simultaneously. You can say an array is a list of items, which is defined in the same manner as a variable but which holds multiple values.
#! /bin/bash
names="Tom Jane Alice Kevin"
for name in $names
do
echo "Hi, $name"
done
Here “names” is defined as an array (holding more than one value) before the start of the loop. Then, this array is used as a list in the for loop. As a result, you will get the following output.
./hello.sh
Hi, Tom Hi, Jane Hi, Alice Hi, Kevin
Loop Over Elements of a File
You can specify a file as a list using $( ); also. An example of this is displayed below.
#! /bin/bash
for name in $(cat studentnames.txt);
do
echo "The student’s name is $name"
done
In this example, a file named studentnames.txt is specified as a list. For this script to work, a text file with this name is already created having the names of students. The cat command is used for optimization and its results in terms of improved speed can be observed when the size of the file is very large. The output of the above script is shown below.
./hello.sh
The student's name is Nigel The student's name is Hogarth The student's name is Kuki The student's name is Wally The student's name is Abby
The C-Style Bash for Loop
You can write a for loop in conventional and popular C language style, as shown below:
#! /bin/bash
for ((i=0; i < 10; i++))
do
echo $i
done
You have noticed that the loop starts with the keyword for, which is followed by a condition (written in double brackets). This condition specifies the number of times the loop is going to execute. The body of for loop is enclosed in do-done keyword pair showing the start and end of the for loop respectively.
Inside the condition, i is the loop variable, which acts as a counter i.e., it counts the number of iterations of a loop. The loop variable has an initial or starting value (in this case i = 0), an ending value (i = 10) and an incrementing value (i++). Incrementing value means that the value of the loop variable will increment by this amount in each iteration (in this example, the value of i is incremented by 1).
You have to write all the Linux commands you want to execute multiple times in the body of the loop (means inside of do and done pair).
In the above example, the initial value of i is 0, which is less than 10, so the loop will execute for the first time, and the value of i is incremented by 1. In the second iteration, the value of i (which is now 1) is again checked with the ending value. As the current value is still less than 10, so the loop will again execute and increment the value of i by 1.
The process will continue until the value of i reaches the ending value. When the value of i reaches 10 and is checked against the ending value, the loop will stop. Because now the value of i is not less than 10 and the condition became false.
So, this loop will execute 10 times (from 0 to 9), which means all commands written inside the loop will be executed 10 times. In this case, there is only one echo command in the loop used to print the value of the loop variable i. The output of the above for loop will be like this:
./hello.sh
0 1 2 3 4 5 6 7 8 9
Some important points to note are:
- You can set any starting value, but to make things easy the starting value normally starts from 0 or 1.
- You can give any name to the loop variable (like x, p, d, etc.) or even a multi-character name (like filename, var, etc.), but it is a programming convention that loop variables are usually given names like i, j, and k.
- The value of the loop variable is usually incremented by 1 (like i++), but you can increment this value by more than one (like i = i + 2 or increment by any other number).
Infinite Loop
An infinite loop is a loop that keeps on looping and never exits. You can create an infinite for loop using the following way.
for (( ; ; ))
do
…
…
…
done
As you can see, nothing is mentioned in the for loop (no initial value, no final condition, and no increment). Remember that this loop will never end, so you have to use Ctrl + Z to stop it forcibly.
Practical Examples of for Loop in Bash Scripts
Taking Backups
Suppose you want to take a backup of all the files present in a folder to another subfolder (you named as backup). Instead of manually taking the backup and executing the cp commands for all the files, you can write a script and use a for loop in it, as shown below.
#! /bin/bash
for filename in *
do
cp $filename backup/$filename
done
In the above example, filename is the loop variable (remember it is not necessary to use i always, as here filename is more meaningful to use than i). When this variable is preceded by a $, it represents the value contained in the variable. This is similar to the examples given above, where $i is used to print the value of i in the echo command.
By using the for loop, as shown above, the cp command will be executed for all the files in the current folder (see the * sign is used as a list). Each time this loop will execute the variable filename will hold the name of a new file. As a result, the copies of all files with their original names (due to the second $filename) will be created in the backup folder.
Renaming Files
You can use a for loop to rename multiple files at a time. Suppose you want to append the word “old” with the names of all text files present in your current directory. Then you can use the following script.
#! /bin/bash
for file in $(ls *.txt)
do
mv $file "old"-$file
done
Here for each file in the output of the ls command, the move command will change the file name.
-rw-rw-rw-- 1 edxd edxd 0 Dec 21 10:13 old-1.txt -rw-rw-rw-- 1 edxd edxd 0 Dec 21 10:13 old-2.txt -rw-rw-rw-- 1 edxd edxd 0 Dec 21 10:13 old-3.txt
Conclusion
Now you know the basics of the for loop and different ways of writing it. There are various ways to use it to write commands that need running multiple times. You can use the for loop to save time and effort.