Skip to content

Loops#

With the if/else statement, we're able to change the "direction" of our code. With a loop, we can repeat code, over and over, based on some other value or range.

The simplest loop to understand is the for loop. Let's change our code, again, so repeat our message over and over:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash

yourname=$1

default_name() {
  yourname="reader!"
}

nondefault_name() {
  echo "Thank you for providing a name :-)"
}

if [ -z $yourname ]
then
  default_name
else
  nondefault_name
fi

hello() {
  echo "Hello"
}

world() {
  echo "world"
}

hello
world

for i in 1 2 3 4 5
do
  echo "$(hello), $(world)! My name is ${yourname}"
done

We're telling our script to loop over a range of number, 1 2 3 4 5 (the spaces are important) and then run what is between the do and the done. Here's the result:

1
2
3
4
5
6
7
8
9
$ bash script_example_4.sh Michael
Thank you for providing a name :-)
Hello
world
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael

That's a bit bonkers, but it demonstrates a for loop quite nicely.

To understand what's going on here, let's write out the loop in plain English: "for in ; do this thing until; done. And when do we reach "done"? In this case, when the list of numbers finishes. Look at the output again:

1
2
3
4
5
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael
Hello, world! My name is Michael

There are five lines. We had five numbers in our list: 1 2 3 4 5. The definition of "done" for our loop is when the list has ended or has been looped over completely. We're keeping things simple right now.

We can demonstrate this further with another example, which you can just copy/paste to the terminal:

1
for file in $(ls); do echo "Filename: ${file}"; done

I get the following:

1
2
3
4
5
6
7
8
$ for file in $(ls); do echo "Filename: ${file}"; done
Filename: datetimescript.sh
Filename: git
Filename: myscript.sh
Filename: script_example_2.sh
Filename: script_example_3.sh
Filename: script_example_4.sh
Filename: simple_script.sh

So our for loop iterated over a list which was made up of the files that the ls file found for us.

So the syntax of a for loop is simple:

1
2
3
4
for variable in list
do
    commands
done

And what is "variable" for, exactly? Why is it there and how do we use it? We can see in our ls based example, above, that it can be used just like any other variable but only inside the loop's body. You cannot use the variable after you've left the loop (after the done part.) We can demonstrate this with another update to our script:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#!/bin/bash

yourname=$1

default_name() {
  yourname="reader!"
}

nondefault_name() {
  echo "Thank you for providing a name :-)"
}

if [ -z $yourname ]
then
  default_name
else
  nondefault_name
fi

hello() {
  echo "Hello"
}

world() {
  echo "world"
}

hello
world

for i in 1 2 3 4 5
do
  echo "${i}: $(hello), $(world)! My name is ${yourname}"
done

Which gives me the output:

1
2
3
4
5
6
7
8
$ bash script_example_4.sh
Hello
world
1: Hello, world! My name is reader!
2: Hello, world! My name is reader!
3: Hello, world! My name is reader!
4: Hello, world! My name is reader!
5: Hello, world! My name is reader!

Which means that $i is the number in the list. It's updated as the loop literally loops over the list. Try making the list of numbers shorter or longer and see what happens.