Bash For Loops: Guide to Iteration in Linux

For loops in Bash are vital control structures used in scripting to repeat tasks. They offer the ability to execute a series of commands multiple times, looping over ranges, variables, command outputs, and more.

This comprehensive tutorial will take you through various ways to utilize for loops in Bash.

From basic syntax to more advanced topics like nested loops and dynamic sequence generation.

 

 

Basic Syntax

A for loop in Bash generally follows this syntax:

for VARIABLE in ELEMENT_1 ELEMENT_2 ... ELEMENT_N
do
    COMMAND1
    COMMAND2
    ...
done

Here, the loop iterates over the elements and performs the commands enclosed between do and done.
Now, if you run this simple example:

for i in 1 2 3
do
   echo $i
done

Output:

1
2
3

In this code, the loop iterates three times, setting the variable i to the values 1, 2, and 3 in each iteration, respectively. It then prints the value of i, resulting in the above output.

 

Iterating a Sequence of Numbers

In Linux Bash, you can easily iterate over a sequence of numbers. Here’s how:

for number in {1..5}
do
   echo $number
done

Output:

1
2
3
4
5

The loop runs five times, with the variable number taking the values from 1 to 5 in sequence. The echo command prints these values one by one, line by line.

 

For Loop with Range

You can create loops in Bash with a specified range using the syntax {START..END..INCREMENT}. Here’s an example:

for number in {0..10..2}
do
   echo $number
done

Output:

0
2
4
6
8
10

This loop iterates over the numbers from 0 to 10 in increments of 2. The variable number is assigned these values sequentially, and they are printed line by line.

 

Iterating Over Strings

Iterating over strings is straightforward in Bash. Here’s an example:

for string in "apple" "banana" "cherry"
do
   echo $string
done

Output:

apple
banana
cherry

Here, the loop iterates three times, each time assigning a different fruit name to the variable string. Consequently, it prints these fruit names.

 

Iterating over Command Output

You can iterate over the output of a command in Bash. Here’s how to list all the text files in a directory:

for file in $(ls *.txt)
do
   echo $file
done

Output:

file1.txt
file2.txt
file3.txt

The loop runs the ls *.txt command and get the names of all text files in the directory.

The variable file then takes each filename in turn, and the echo command prints them.

 

Looping Over Files and Directories

Here’s an example to list all the directories within the current folder:

for dir in */
do
   echo $dir
done

Output:

dir1/
dir2/
dir3/

In this case, the loop iterates over all the directories in the current folder, denoted by the trailing slash */.

The variable dir takes the value of each directory name in turn, and the echo command prints them.

 

Loop Control Statements

Loop control statements help in controlling the flow within a loop.

break

Terminates the loop. Example:

for number in {1..5}
do
   if [ $number -eq 3 ]; then
      break
   fi
   echo $number
done

Output:

1
2

The loop exits when number equals 3, resulting in only 1 and 2 being printed.

continue

Skips to the next iteration. Example:

for number in {1..5}
do
   if [ $number -eq 3 ]; then
      continue
   fi
   echo $number
done

Output:

1
2
4
5

The loop skips printing 3 and continues with the other numbers.

exit

Exits the entire script. Example:

for number in {1..5}
do
   if [ $number -eq 3 ]; then
      exit
   fi
   echo $number
done

Output:

1
2

The entire script is terminated when number equals 3, and no further code is executed.

 

Nested For Loops

Nested for loops consist of one or more loops within another loop. Here’s an example that uses two nested loops to create a multiplication table:

for i in {1..3}
do
   for j in {1..3}
   do
      echo -n "$((i * j)) "
   done
   echo
done

Output:

1 2 3 
2 4 6 
3 6 9

Here, the outer loop iterates over the numbers 1 to 3, and the inner loop does the same.

Inside the inner loop, the product of the variables i and j is printed, creating a 3×3 multiplication table.

 

Dynamic Generation of Loop Sequences (using seq)

You can use the seq command dynamically generate for loops sequences. Here’s an example:

for number in $(seq 1 2 9)
do
   echo $number
done

Output:

1
3
5
7
9

Here, the seq 1 2 9 command generates a sequence of numbers from 1 to 9, incrementing by 2.

The loop iterates over these numbers, printing them line by line.

 

Infinite Bash for Loop

An infinite loop continues indefinitely without a termination condition. Here’s a simple example:

for (( ; ; ))
do
   echo "This is an infinite loop."
   sleep 1
done

Output:

This is an infinite loop.
This is an infinite loop.
...

When to Use Infinite Loops: Infinite loops can be useful for tasks that need to continue without stopping, such as monitoring a system process or waiting for a specific event.
How to Stop It: To stop an infinite loop, you use a termination command like CTRL+C.
Infinite loops must be used with caution, as they can potentially consume system resources if not managed properly.

 

C-Style

Bash supports C-style for loops, providing a familiar syntax for those familiar with programming in C. Here’s an example:

for (( i=0; i<3; i++ ))
do
   echo "Iteration number $i"
done

Output:

Iteration number 0
Iteration number 1
Iteration number 2

This loop begins with i set to 0 and continues while i is less than 3, incrementing i by 1 at each iteration. It prints the iteration number for each value of i.

 

Using $@ & $*

In Bash, $@ and $* are special variables that deal with command-line arguments, and they can be used within loops. Here’s how:

for arg in "$@"
do
   echo $arg
done

Output (if script is called with ./script.sh one two three):

one
two
three

$@ treats each argument as a separate word, and the loop prints them one by one.

Using $*:

for arg in "$*"
do
   echo $arg
done

Output (if script is called with ./script.sh one two three):

one two three

$* treats all arguments as a single string, so the loop prints them on one line.

8 thoughts on “Bash For Loops: Guide to Iteration in Linux
  1. In the last example there is:

    for folder in $PATH
    How does the script know to look in actual folders. We never used -d to specify we wanted to look in directories.

    1. When we use the asterisk * it means all files and directories in that folder.
      So we get files and directories BOTH of them without filtering.
      The filtration to get the folders is on the second if statement which is.

      for file in $folder/*

      Then we search for the executable with -x

    2. If I understood your question: I think the $PATH global variable only contains a list of folders in which the executables are stored, separated by “:”. To see these folders on your system just type echo $PATH. On my system, it returns the string “/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin”
      None of those can be a file, so he didn’t need to filter.

        1. GREAT articles btw! I’m learning SO MUCH!
          I started at Linux file system->Main Linux Commands->Main Linux Commands (Part 2) -> Linux Environment Variables -> Linux Command Line Tricks -> Bash Script Step-by-Step ->Bash Scripting Part 2 -> Part 3 where I am currently 🙂
          Thanks, and don’t stop delivering!

          1. Great to know that.
            I do my best to post quality content.
            Hope the community loves it.
            Regards.

Leave a Reply

Your email address will not be published. Required fields are marked *