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.
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
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
The syntax above will open our script
in 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
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
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.
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.
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.
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
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
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.
Mokhtar is the founder of LikeGeeks.com. He works as a Linux system administrator since 2010. He is responsible for maintaining, securing, and troubleshooting Linux servers for multiple clients around the world. He loves writing shell and Python scripts to automate his work.
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.
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
Now I get it. Thanks.
For a nearly total noob it is confusing 😛
You are always welcome.
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.
Great comment really.
Thanks for the contribution.
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!
Great to know that.
I do my best to post quality content.
Hope the community loves it.
Regards.