For loop

For loop is used to perform set of commands on a list of items. List is a series of strings, separated by spaces.

The for loop will iterate each item in the list (in order) and assign the current item value in the defined variable and executes the commands defined in a block between do and done and return at the top for a new iteration round with a next item in the list.

The first line of for loop starts with the word for followed by a variable name, followed by the word in an then a list of items.
The next line contains a do statement, note that then statement is no longer used. Place the commands that will executed on the following lines and finally, end the loop with a word done.

The basic syntax:

#!/bin/bash

for <variable> in <list>
do
  <commands>
done

The following example shows how to iterate a list of items and print item values.

#!/bin/bash

for ANIMAL in dog cat cow
do
  echo "animal: ${ANIMAL}"
done

#output:
#animal: dog
#animal: cat
#animal: cow

#Note:
List of items can be just a string (word will be splitted by spaces)!
Remember that if you want to disable this functionality, quote your variable reference!

ANIMALS="dog cat cow"
for ANIMAL in ${ANIMALS}
do
  echo "animal: ${ANIMAL}"
done

For loop within a range

As a JAMK student, you have studied a Python programming language in basic of programming course and perhaps remember that in Python you has to use range with a for loop if you just wanted tpo define number of rounds to be iterated.
Same principle applies with a bash scripts, except bash doesnt have a named function range that we can use.

The basic idea is to define a range using a curly braces ({}) and integer values: starting and ending value. Note that there is not spaces between the values and curly braces!

#!/bin/bash

for <variable> in {1..5}
do
  <commands>
done

The following example shows how to print a string "hello" five times.

#!/bin/bash

var="HELLO"

for x in {1..5}
do
  echo ${var}
done

#output:
#HELLO
#HELLO
#HELLO
#HELLO
#HELLO

It's also possible to define the step size. This means how big the steps (increase the variable by x) are taken between the iteration rounds. This can be done by adding a nother two dots and a step size at the end.

#!/bin/bash

for x in {1..10..2} #from 1 to 10 but the step size is 2
do
  echo ${x}
done

#output:
#1
#3
#5
#7
#9

In earlier examples, the value was increased on every iteration round. It's possible to flip the syntax to decrease the value on every round.

#!/bin/bash

for x in {5..0}
do
  echo ${x}
done

#output:
#5
#4
#3
#2
#1
#0

While

while loop is used perform a set of commands while the given expression is true (iteration). When the expression is no longer true (false) iteration stops.

The basic syntax:

#!/bin/bash

while [ <test> ]
do
  <commands>
done

Note that the syntax is not fully similar with a for loop. Same do and done statements, but like with a if statements, square brackets ([]) must be used to encapsulate the test.

The following example shows how to print the number of current iteration round until the value is 5.

#!/bin/bash

count=1 #initialize the  helper variable with a value 1
while [ ${count} -le 5 ] #while the COUNT value is less or equal than 5 (true), perform the following commands
do
  echo ${count} # print the current value
  ((count++)) #increase the value by 1
done

#output:
#1
#2
#3
#4
#5

Until

Until loop is pretty similar with a while loop, except the command block is executed until the defined test becomes true. So in other words, commands are executed while test return a false value and will iteration rounds will be stopped when the test condition becomes true.

The syntax is like a while loop, except the keyword used is until, not a while.

The basic syntax:

#!/bin/bash

until [ <test> ]
do
  <commands>
done

The following example shows how to perform earlier example with a until statement.

#!/bin/bash

count=1

until [ ${count} -gt 5 ]
do
  echo ${count}
  ((count++))
done

#output:
#1
#2
#3
#4
#5

Break and Continue

In the most cases your loops are iterated through in a ordenly manner until a certain condition is changed to false. Sometimes there is a need to stop the loop early or skip certain commands if something happens. For that we have statements: break and continue.

A break statement exits from the loop immediately. Note that this doesn't quit the whole script, unless the loop where it's defined is in the "1st level" (on the left side) and there is no other commands after the loop.

For example, we want to end the loop when we find a student called "Mika" from a list of students.

#!/bin/bash

students="Olli Laura Mika Juuso Paula"

for x in ${students}
do
  if [ ${x} = "Mika" ]
  then
    echo "${x} was found! ending the search!"
    break
  fi
  echo "The current user was: ${x} "
done

#output:
#Olli
#Laura
#Mika was found! ending the search!

A continue statement skips everything thats defined after it on command block of the iteration and starts the new iteration round from the beginning.

Lets use the earlier example. You want to print every other student name except Laura.

#!/bin/bash

students="Olli Laura Mika Juuso Paula"

for x in ${students}
do
  if [ ${x} = "Laura" ]
  then
    continue
  fi
  echo ${x}
done

#output:
#Olli
#Mika
#Juuso
#Paula


Select

A select statement can be used to create a simple selection menus where all the items in the defined list are printed with a number to a user. This automatically allows user to select the wanted item by entering a correlating number. After this the commands linked to teh given item are executed and finally a new prompr is printed to a user.

The basic syntax:

#!/bin/bash

select variable in <list>
do
  <commands>
done

In the following example, user can select from the three options, 2 for dummy printing and one for exiting:

#!/bin/bash

OPTIONS="Printer1 Printer2 Exit"

#PS3='Select: '
#this is optional, PS3 system variable is used to print out the wanted string when asking the number from the user, the default value is #?

select x in ${OPTIONS}
do
  if [ ${x} = "Exit" ]
  then
    break
  fi
  echo "Im just a dummy printer ${x}"
done
echo "exiting..."