02. Flow Control

Arindam BaidyaArindam Baidya
5 min read

Conditional logic

if - else

if [ "$rocket_status" = "Failed" ]
then
    rocket-debug "$mission_name"
elif [ "$rocket_status" = "Success" ]
then
    echo "This is successful"
else
    echo "The status is not failed or success"
fi
  • In if-else, we use square brackets [] to put the condition inside which needs to be checked

  • We use then to perform some operations/print the status is condition met

  • During else-if we use elif

  • We close the if-else block using fi (reverse of if)

  • We need to keep space between operator and operands as well as with square brackets []

  • Only string can be checked with equal-to (=; !=) operator

  • Conditional operation using double square brackets( [[ ]] ) works similarly to single pare square brackets [ ] but it is an enhanced version and supports additional operations, like matching patterns, using expressions.

AND-OR

  • For single square brackets, we need to use different pairs of single square brackets

  • For Double square brackets, we can check within a single double-bracket pair

File-level operator

Loops - For

If we have to do the same task again and again, we can simplify it using for loops. It is an automation process that automates a script.

# Loop through each mission
for mission in <list of missions> # lunar-mission jupiter-mission saturn-mission
do
  bash /home/bob/create-and-launch-rocket "$mission"
done

Here, do and done is the start and end of the for loop. Every time the loop runs, it will iterate to the next mission from the list. create-and-launch-rocket is another script file, which is a general script file made for creating and launching a rocket based on the argument.

When there are too many arguments, it is hard to type all the name from the list in the script. To rid of from that situation, we can make another file with a list of arguments, and point that file in the script file.

# Loop through each mission name in the file
# for mission in `cat mission-names.txt` -> Is not recommended
for mission in $(cat mission-names.txt) # Is a good practice
do
  create-and-launch-rocket "$mission"
done

This time when the for loop is run, before the for loop, the cat command will execute to print all the mission names, which will then used as a input to the for loop. We can now only update the mission-name.txt file, and no need to touch the script file.

Do not use the backtracks `cat mission-names.txt` to specify a command. Instead, use to $(cat mission-names.txt) because this format is easier to read and has an advantage when we plan to embed multiple command (commands within commands).

These are two ways of running a for-loop. But when we need to run a loop 100 times suppose, there is an easier way.

We can also use for loop as we do in other programming languages.

Q. When to use for loops

  • Execute a command or a set of commands many times

  • Iterate through files

  • Iterate through lines within a file

  • Iterate through the output of a command

# Loop from 0 to 100
for (( mission = 0; mission <= 100; mission++ ))
do
  create-and-launch-rocket "mission-$mission"
done

This time we need to use double parentheses (( )).

Real-world examples

# Loop through each file in the current directory
for file in $(ls)
do
  echo "Line count of $file is $(cat $file | wc -l)"
done

This script uses a for loop to list all files in the current directory, then uses cat and wc -l to count and display the number of lines in each file.

# Loop through each package name in the file
for package in $(cat install-package.txt)
do
  sudo apt-get -y install "$package"
done

This script reads package names from the install-package.txt file and iterates over each name, executing the sudo apt-get -y install command to install each package.

# Loop through each server name in the file
for server in $(cat server.txt)
do
  ssh "$server" "uptime"
done

This script reads server names from the server.txt file and iterates over each name, using ssh it to connect to each server and execute the uptime command. Make sure you have the necessary SSH access to each server. It will work fine when we use a passwordless SSH server, otherwise, we need to provide a password each time.

Loops - While

while [ "$rocket_status" = "launching" ]
do
    sleep 2
    rocket_status=$(rocket-status "$mission_name")
done

Q. When to use while loop ?

  • Execute a command or a set of commands multiple times, but we are not sure how many times.

  • Execute a command or a set of commands until a specific condition occurs

  • Creating infinite loop

  • For Menu driven programs

Real-life use cases

while true
do
    echo "1. Shutdown"
    echo "2. Restart"
    echo "3. Exit Menu"
    read -p "Enter your choice: " choice

    if [ "$choice" -eq 1 ]
    then
        shutdown now
    elif [ "$choice" -eq 2 ]
    then
        shutdown -r now
    elif [ "$choice" -eq 3 ]
    then
        break
    else
        continue
    fi
done

Case statements

Case statement (switch case) in shell scripting, start with case and end with esac (reverse of the case). Each case in the case block starts with 1), 2), 3), .. *) and end with the double colon ;;. Here *) represent default case.

while true
do
    echo "1. Shutdown"
    echo "2. Restart"
    echo "3. Exit Menu"
    read -p "Enter your choice: " choice

    case $choice in
        1) shutdown now ;;
        2) shutdown -r now ;;
        3) break ;;
        *) continue ;;
    esac
done

Note:

  • Always don’t use any spaces between variable name, equal to (=), and value when defining/initializing a variable.

  • It is possible to run a case in bash script correctly when we don’t use double colon (;;) at the end statement (e.g., *) continue )

References

KodeKloud

0
Subscribe to my newsletter

Read articles from Arindam Baidya directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arindam Baidya
Arindam Baidya