Sage-Code Laboratory
index<--

Control Flow

Imagine a program like a chemical plant. It has pipes, rezervoirs and reaction recipients. The liquid flows along and is controlled by actuators, fossets and valves. Analogic we can control the logical flow of a program using specific statements.

Control flow statements are introduced by structured programming languages. Fortran, Pascal, Ada, C all these have similar control flow statements. Modern languages are using also control flow statements.

Next we enumerate only the most popular control flow statements you can find in programming languages. These are implemented a bit different in Bash but the functionality is the same in all languages.

Popular statements

Decision

The most common and maybe the most important control flow statement in programming is the decision statement. A decision is based on a conditional expression that is also known as logical expression. You must understand propositional logic to be able to make correct conditions. Check next diagram to understand the decision workflow diagram.

decision

Decision Diagram

decision.sh
#!/bin/bash
# demo how to deal with Boolean
a=true
if $a; then
   echo "0. expected"
fi
# test 1: b is defined but later
if $b; then
   echo "1. unexpected"
else
   echo "1. expected"
fi
# variable b is defined later
b=false
# test 2 compare booleans
if [ $a != $b ]; then
   echo "2. expected"
else
   echo "2. unexpected"
fi
# use quotes to compare strings
# much safer approach
if [ "$a" == "$b" ]; then
   echo "3. unexepected"
else
   echo "3. expected"
fi
Console
~/bash-repl$ bash decision.sh
0. expected
1. unexpected
2. expected
3. expected
~/bash-repl$ 

Repetition

Repetition is a block of code containing several statements that can be executed multiple times. The number of times is determined by a control condition. Sometimes the repetition is forever and this is called infinite loop. There are 2 kind of repetition statements in Python: "while" and "for".

While statement

The while statement is used for repeated execution as long as a conditional expression is true. The conditional expression can depend of a control variable that is modified inside the repetitive block. The expression is evaluated for each iteration. When the expression result becomes false the block is terminated.

while loop

While Loop

Note: While repeatedly tests the conditional expression and, if the result is true, it executes the repetitive block. When the expression is false the next statement after keyword "done" is executed.

for-int.sh
#!/bin/bash
#source script
let x=0
echo "start x = 0"
while [[ $x -lt 5 ]]
do
     echo "x = $x"
     let x+=1
done
echo "final x = $x"

# in reverse order
while (( $x > 0 ))
do
     echo "x = $x"
     let x-=1
done
echo "final x = $x"
Console
~/bash-repl$ bash while.sh
start x = 0
x = 0
x = 1
x = 2
x = 3
x = 4
final x = 5
x = 5
x = 4
x = 3
x = 2
x = 1
final x = 0
~/bash-repl$ 

For statement

The classic for statement in Bash is similar to Java or C. In tbis form the loop has three components separated by semicolons. Not all 3 are executed in the same time:

  1. the init statement: executed before the first iteration
  2. the condition expression: evaluated before every iteration
  3. the post statement: executed at the end of every iteration
classic-for

Iteration Diagram

Note: You can intrerupt any loop using "break" statement. Also you can shortcut execution of a loop using "continue". Howeve, the interpretation of post is happening at the right time so there is no danger that you enter in infinite loop.

for-int.sh
#!/bin/bash

# for loop interuptions
for (( i=0; i<=100; i++ ))
do
   # Output only even numbers
   if ((  i % 2 == 0 )); then
      echo "Element $i"
      continue
   fi

   # intreruption conditional
   if (( i > 20 )); then
      break
   fi
done
Console
~/bash-repl$ bash for-int.sh
Element 0
Element 2
Element 4
Element 6
Element 8
Element 10
Element 12
Element 14
Element 16
Element 18
Element 20
~/bash-repl$ 

Range pattern

In bash, the for loop can be used with a range generator that is similar to Python language. In this case there is no need for all 3 expressions and the syntax is a little different.

range.sh
#!/bin/bash

# normal range
for i in {0..5}
do
  echo "Element $i"
done

echo ------------------

# reverse range
# with ratio 2
for i in {10..0..2}
do
  echo "Element $i"
done
Console
~/bash-repl$ bash range.sh
Element 0
Element 1
Element 2
Element 3
Element 4
Element 5
------------------
Element 10
Element 8
Element 6
Element 4
Element 2
Element 0
~/bash-repl$ 

Visitor pattern

A better way to use for loop is when you use it to visit elements of an array. It is specially difficult to use classic for loop with arrays due to existence of gaps in Bash arrays. To avoid possible errors finding the elements it is safe to use this pattern.

array.sh
# initialize an array
myArray=(1 2 "three" 4 "five")

#visit all elements
for t in ${myArray[@]}; do
  echo $t
done
echo "-------------------"

#visit all element by index
for t in ${!myArray[@]}; do
  echo ${myArray[$t]}
done
Console
~/bash-repl$ bash array.sh
1
2
three
4
five
-------------------
1
2
three
4
five
~/bash-repl$ 

Selection

A REPL application is a classic example for selection statement. You can display a menu and then read the input. To select one option, you enter a number from keyboard. Then you use a jump table or a selection statement to execute one or other feature or command from the script. Then, you repeat in a loop, reading next option.

repl

REPL Application

Demo Code

Next scripts are some of the REPL examples. You do not have to understand these scripts rigt now just browse the syntax then read the notes. If you are an experienced programmer use your chritical thinking skills to judge if you like this language. If you hate it, don't continue but look the other way.

selection.sh
# demo for selection
echo "sub-menu:"
options="one two three break"
# demonstrate selection
select x in $options; 
do
  # demonstrate decision ladder
  if [ "$x" == "break" ]; then
    echo "done" 
    break # exit selection
  elif [ "$x" == "one" ]; then
    echo "one"
  else
    echo "other"
  fi #end if
done
Console
~/bash-repl$ bash selection.sh
1) one
2) two
3) three
4) break
#? 1
one
#? 2
other
#? 3
other
#? 4
done
~/bash-repl$ 

Notes:

  1. In Bash we can have global scope;
  2. In global scope we can have commands and declartions;
  3. One statement can be on multiple lines of code;
  4. Bash do not have switch but select instead;

Your homework

Visit replit.com website and run the following example. You can enter an option and see it running. Select second option (2) to print: hello world, then (1) to exit. Inspect the code. This is the example we will use to explain many things in our next articles.

Open: bash-repl app on repl.it


Read next: Functions