how to use 'for' loop in bash shell scripts

If you have done any programming in any language, you should be familiar with loops. Almost all computer programming languages have some version of a loop statement. It is a language construct that allows you to execute a specific piece of code repeatedly, often with different set of data.

In this post, we will talk specifically about the for loop in bash shell script.

general syntax of 'for' loops

for variable in value list
do
     command1
     command2
     ......
done
  • variable is a character sequence that holds a value.
  • value list is a set of values that the variable can have.
  • command is set of instructions that are executed.

The for loop in bash is going to evaluate the expression denoted by value list (if it is a command) and generate a list values. It is then going to assign each of the generated values to the variable and then execute the commands for each of those values.

The ability to evaluate the list of values gives the loop great flexibility. We will look at several examples as to how you can use them.

numerical set of values

Let's say you want to execute the for loop in bash with numerical values, from 1 to 3. then you could use the for loop as

for x in 1 2 3
do
    echo "current value : $x"
done

Now, if you want to execute the for loop with numerical values from 1 to 20, then you can use the brace expansion syntax. You probably don't want to type out all integers between 1 and 20.

for x in {1..20}
do
    echo "current value : $x"
done

list of strings as values

Ok, so now integers and numbers are not the only thing you can use as values. You can have strings as values as well.

for x in this is a set of string values
do
    echo "current value : $x"
done

Note that there are no quotes around the string. If you put quotes around the string then it will be considered as one string. If you need to have string values with spaces in them then you use the quotes.

for x in "this is" "a set of" string values
do
    echo "current value : $x"
done

wildcard as values

You can also use wildcards as values in the for loop. This is especially useful when you want to files or filenames as values in the loop.

for x in images/*.jpg
do
    echo "current value : $x"
done

The above example will get all files with a jpg extension. Now you can do any operation on these files. This is an example of performing batch operations in the bash shell on a set of files.

commands as values

You can provide a command as value as well with in the bash for loop. The set of values that the command output will be the values that the variable gets. For example, here is an example of a script that will optimize all the jpg files in the folder.

#!/bin/bash
for i in $(find . -maxdepth 1 -type f -iname "*.jpg" -exec basename '{}' \;); do
        echo "--- Start on $i ------"
        jpegtran -optimize -copy none -progressive -outfile $i original-$i
        echo "--- Done with $i ------"
done;

Now that you know how to use an expression or command as the input to the bash for loop, there is another variation of the for loop that takes three expressions.

the three expression syntax of for loops

The general syntax is :

for (( expression1; expression2; expression3 ))
do
     commands;
done

A simple example would be the integer version, as in the earlier examples. Here the bash for loops over numerical values ranging from 1 to 20, as in the example above which used the brace notation.

for (( i = 0; i <= 20 ; i++ ))
do
    echo $i
done

You can pretty much use any expression or command here. Ideally, the first expression would assign the initial values to the variables you want to use. The second expression will run after every loop and is the termination expression. The loop will terminate if this expression returns false. The third expression allow you to set new values to your variables.