Bash Scripting Part2 – For and While Loops With Examples

In the first part of this Bash Scripting tutorial, we discussed how to write a Bash script. We explored the various usages and unique scenarios in which Bash scripts can come in handy, making a great example of how incredible they can be.

In this part of the tutorial, we will take a look at the for command, and the while command. We’ll show how we can use these commands to make loops to iterate over a series of values.

 

 

The For Loop

In Linux, a loop is what we use to execute commands at a specified interval repeatedly. Loops are used in a large variety of programming languages for the same purpose.

There are multiple different types of loops in Linux, but in this section of the article, we will focus on the for loop.

#!/bin/bash
 for y in a b c d w x y z 
> do
> echo $y
done

As you can see in the screenshot above, we attributed the “y” variable — which is just a meaningless placeholder used for the sake of the command — to a few letters of the alphabet.

We then passed that variable to the echo command, and it was able to output our letters below.

Using the for command to echo some example text

 

Iterating Over Simple Values

We can use the for command in a Bash script. To do this, we first need to create a text file in our Linux terminal. You can utilize the touch command for easily creating text files.

$ touch script

Using the touch command to create a text file that we’ll use to make our script

The syntax above will create a text file we’ll call “script”. Please make sure to create your text file using the .sh file extention. Upon creating script, we’ll want to edit in our actual script containing the for command.

We can achieve this by running a couple of different text file editing commands, such as the nano command, and the vi command, etc.

But we’d recommend just going with nano, as it’s one of the most simple and easy to use command text editors in Linux.

$ nano script

Using the nano command to open our “script” text file in the nano text editor so we can write in our script.

The syntax above will open our scriptin the nano text editor. Here, we’ll want to type in our script.

Note that this text file must contain #!/bin/bash, which informs the Bash script about which shell to use, so it is a pivotal component of successfully creating a Bash script.

#!/bin/bash
for var in first second third fourth fifth; do
	echo The $var item
done

Using the for command in a Linux Bash script and running it

 

Iterating Over Complex Values

In the previous example, we showed how to use for command to iterate over simple values in a user made Bash script. The word simple here refers to values that contain just a single word.

But sometimes, you’ll have a list that includes — instead of what we saw in the previous example with “first” — something along the lines of “the first,” which happens to contain more than one word for a single value. These values are what we call “complex” values.

If your list does have these complex values, you’ll need to reference them by surrounding them in quotes, so the script will understand that it’s just one value.

#!/bin/bash
for var in first "the second" "the third" "I’ll do it"; do
	echo "This is: $var"
done

Using quotation marks to reference multiple word values in our Bash script in Linux

 

Command Substitution

We can also use command substitution in our for command in our Bash script.

#!/bin/bash
my_file="file01"
for var in $(cat $my_file); do
        echo " $var"
done

Here we used command substitution with a Bash subshell, as seen by the use of the cat command inside of $( ); this allows us to use the output from the cat command and get the content of the file assuming that each line has one word.

But if there are spaces in one of these lines, every word will be considered a field. In this case, you will need to tell the shell to treat new lines as a separator instead of spaces.

Using the output of the cat command inside of the for command.

 

The Field Separator

By default, the following characters are considered as fields by the Bash shell.

  • Space
  • Tab
  • new line

If your text includes any of these characters, the shell will assume it’s a new field, and you’ll have to change the internal field separator or IFS environment variable if you need to use these characters.

$ IFS=$’n’

The syntax above will cause the Bash shell to consider new lines as a separator instead of a space character.

#!/bin/bash
file="/etc/passwd"
IFS=$'n'
for var in $(cat $file); do
	echo " $var"
done

You can also assign the field separator to colons with IFS like shown below.

$ IFS=:

Pretty fantastic, huh?

 

Iterating Over Directory Files

You can also use the for loop in a Bash script to list the files in your home directory.

#!/bin/bash
for obj in /home/ubuntu/*; do
	if [ -d "$obj" ]; then
		echo "$obj is a folder"
	elif [ -f "$obj" ]; then
		echo "$obj is a file"
	fi
done

This process requires that you utilize the if statement to check files and folders. But that shouldn’t pose much of a problem for you if you’ve read the previous post. But if by some chance you need a refresher, I’d recommend reviewing it.

Iterating over directory files using the for loop in a Bash script

We utilized a wildcard called an asterisk (*) in our Bash script that contains a for loop that allows us to list the files and folders in our home directory. In Bash scripting, this process is called “file globbing.” File globbing means all existing files with a name.

Note that the variables in our if statement are written with quotation marks because the file or folder names may contain spaces. If we had omitted this step, we might not have been able to list all files and directories.

 

Iterate over file lines

We can use the for loop in a Bash script to iterate over file content:

#!/bin/bash
IFS=$'n'
for text in $(cat /etc/passwd); do
	echo "This line $text ++ contains"
	IFS=:
	for field in $text; do
		echo " $field"
	done
done

Here we have two loops, the first loop iterate over the lines of the file, and the separator is the new line, the second iteration is over the words on the line itself, and the separator is the colon :

file data

You can apply this idea when you have a CSV or any comma-separated values file. The idea is the same; you just have to change the separator to fit your needs.

 

For loop C-Style

If you’re familiar with the C language, you might notice that there’s something a little off about for loops in Linux sometimes.

This is because there exist two ways to write for loops; the standard Linux way, which we’ve already covered at the beginning of this tutorial, and the “C-style” way.

for (var= 0; var < 5; var++)
{
printf(“number is %dn”, var);
}

The syntax above is for the for loop written in C. The C-style for loop in Linux is written very similarly to this with a few small changes, which can be observed below.

for (( variable = start ; condition ; iteration step))

for (( var = 1; var < 5; var++ ))

To help paint the picture better, we’ll include an example Bash script using the C-style for loop in our Linux terminal.

#!/bin/bash
for ((var = 1; var <= 10; var++)); do
	echo "number is $var"
done

Put this in our text file and fire it up.

Using the c-style for loop in a Bash script

 

The Continue Command

The Bash continue command ignores the commands inside of the outer loop for the current iteration and gives control to the next one. You can use this command to stop executing the remaining commands inside a loop without exiting the loop.

In the next couple of examples, we’ll get into how this command can be used in Bash scripting loops in Linux.

 

The Break Command

You can use the break command to exit from any loop, like the while and the until loops.

#!/bin/bash
for number in 10 11 12 13 14 15; do
	if [ $number -eq 14 ]; then
		break
	fi
	echo "Number: $number"
done

The loop runs until it reaches 14 then the command exits the loop.
We’ll get into some more examples of this command a little later.

The While Loop

The for loop is not the only way for looping in Bash scripting. The while loop does the same job, but it checks for a condition before every iteration. The structure of the while loop can be seen below.

while [ condition ]
do
    commands
done

We’ll provide an example with a Bash script.

#!/bin/bash
number=10
while [ $number -gt 4 ]; do
	echo $number
	number=$(($number - 1))
done

The way in which this Bash script works is simple; it starts with the while command to check if the number is greater than zero, then it’ll run the loop, and the number value will be decreased every time by 1. On every loop iteration, the script will print the value of the number. The loop will run until that number hits 0.

 

Nested Loops

You can create loops inside other loops, like the while loop for example. These loops within a loop are called nested loops. We’ll dive into these by first examining how to create a nested for loop in the following example.

 

Multiple for loops (nested for)

In the previous examples so far in this tutorial, we’ve shown how to create for loops in a Bash script in Linux. But there also exists something we call nested for loops. These are loops within other loops, or just multiple loops, to put it simply.

We’ll show you an easy example of what this looks like, along with a brief examination and description of it down below.

for y in a b c d e f
do
    for u in a b c d e f
    do
        echo "$y$u"
    done
done

As you can see in the screenshot above, the output we receive upon running our script in the Linux command line terminal reads as follows: our example text in each for loop is “a b c d e f”.

What our script does, is echo the text in the outer loop alongside the text from the inner loop.

The script continues to output the first field (in this case spaces, we’ll explain this a little later) of the text in the outer loop until every field contained in the inner loop has been outputted.

Upon the completion of the inner loop’s output, our Bash script will then begin to output the following field of the text in the outer loop.

This entire process will be repeated until every field of each loop has been completely printed in the output in your Linux terminal.

 

Multiple while loop (nested while)

Like the nested for command loops, there also exists nested while command loops. These work exactly the same as the nested loops for the for command; a loop inside of another loop.

The syntax below will bear a striking resemblance to the regular while loop, as the structure of a nested while loop is simply an expanded form of the base while loop, which can be observed in the syntax below.

while [condition]
do 
  statements1 
  statements2
  while [condition]
do
  continue
done
  statements3
done

The syntax above will perform specified tasks until the conditions that you’ve selected are met. This is what is called a loop. But since the loop in the example above is nested, this means that one of the tasks that we mentioned above is another loop itself.

 

While Next

We’ve shown how the while loop and the for loop can be very useful for executing complex processes using Bash scripts in Linux.

But sometimes, for various reasons, you’ll need to kill one of the loops in your Bash script. This scenario, as brutal as it sounds, often occurs in system administration work. So, you might want to familiarize yourself with this concept.

In the Bash shell, the break command and the continue command can provide the necessary tools for controlling the flow of your Bash script loops.

We’ll show how these commands work individually with a couple of examples below.

The syntax for utilizing the brea command to exit a while loop is as follows:

$  while [ condition ]
do
    commands
continue
done

The continue command break command work very similarly and can be considered as opposites to each other; the continue command works exactly like the break command, only it continues the loop instead of killing it.

 

Exit While Loop

The break command kills the current loop and gives control to the next command following that loop. You can utilize this process to exit from loops such as for,while, etc. The syntax of the break command is as follows:

$ while [ condition ]
do
    commands
break
done

But like we mentioned above, both the continue command and the break command can be used for other Bash script loops besides the while loop. We’ll show how to use them in the for loop.

 

Exit For Loop

You can use these loop control commands in a for loop. We’ll use the break command to exit the for loop in our Bash script.

#!/bin/bash
for number in 10 11 12 13 14 15; do
	if [ $number -eq 14 ]; then
		break
	fi
	echo "Number: $number"
done

The for loop runs until it reaches the number that we specified in the bash script, which is 14. Upon reaching our specified number, the break command will exit the for loop.

 

Break If Statement

We’ve just shown how we can use break command to exit for loops, but we can also use this command to exit the if statement inside of these Bash script loops.

i=0
while [[ $i -lt 10 ]]
do
  echo "Number: $i"
  ((i++))
  if [[ $i -eq 5 ]]; then
    break
  fi
done

Using the break command in an if statement

 

Continue Statement

We do the same thing we did in the previous example with the continue command as we did with the break command in a while loop in a Bash script.

i=0
while [[ $i -lt 10 ]]; do
  ((i++))
  if [[ "$i" == '5' ]]; then
    continue
  fi
  echo "Number: $i"
done

Using continue command in while loop if statement

 

Closing Thoughts

I hope you’ve learned a new thing or two. Or, at the very least, I hope you were able to review what you already know. My final words today for you would be to keep reading and practicing.

Thank you.

8 thoughts on “Bash Scripting Part2 – For and While Loops With Examples
  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 *