Controlling the Execution Flow With Conditions in Bash
Scripting·51 min read·Jan 1, 2025
In programming, a control statement is a code structure used to manage the flow and logic of a script by conditionally executing (or not executing) a set of instructions based on predicates called conditions.
Conditions and operators
A condition is an expression that when logically evaluated produces a boolean result, which translates to either true or false, that determines whether code should or shouldn't be executed.
These conditions are created using comparison operators, such as == or -eq, that allow to logically compare values between them.
Comparing strings
Checking the identically
To check strings identically, you can use:
-
==to check if two strings are identical. -
!=to check if two strings are different.
For example:
# This condition evaluates to `true` as both strings are identical
"hello" == "hello"
# This condition evaluates to `true` as both strings are different
"hello" != "world"
Checking the lexicographical order
To check strings lexicographical order, you can use:
-
<to check if a string sorts before another. -
>to check if a string sorts after another.
For example:
# This condition evaluates to `true` as 'a' sorts before 'o'
"jack" < "john"
# This condition evaluates to `true` as 'o' sorts after 'a'
"john" > "jack"
Checking pattern matching
To test a string against a regular expression pattern, you can use the =~ operator.
For example:
# This condition evaluates to `true` as the string contains at least one number
"h3llo" =~ [0-9]+
# This condition evaluates to `true` as the string is a valid phone number
"+33698765432" =~ ^(\+33){1}[0-9]{9}$
# This condition evaluates to `true` as the string only contains letters
"helloworld" =~ ^[[:alpha:]]+$
Comparing numbers
Checking the equality
To check numbers equality, you can use:
-
-eqto check if two numbers are equal. -
-neto check if two numbers are not equal.
For example:
# This condition evaluates to `true` as both numbers are equal
123 -eq 123
# This condition evaluates to `true` as both numbers are unequal
123 -ne 321
Checking the inferiority and superiority
To check numbers inferiority, you can use:
-
-ltto check if a number is lesser than another. -
-leto check if a number is lesser or equal to another.
To check numbers superiority, you can use:
-
-gtto check if a number is greater than another. -
-geto check if a number is greater or equal to another.
For example:
# This condition evaluates to `true` as 10 is lesser than 20
10 -lt 20
# This condition evaluates to `true` as 10 is lesser than or equal to 10
10 -le 10
# This condition evaluates to `true` as 20 is greater than 10
20 -gt 10
# This condition evaluates to `true` as 20 is greater than or equal to 20
20 -ge 20
Conditional statements
In programming, conditional expressions alone don't really make sense as they are not enough to determine whether certain code instructions should or shouldn't be executed.
They have to be evaluated by one of the following control statements in charge of deciding on the execution logic of the script.
The if statement
The if statement is used to execute a set of instructions based on the boolean evaluation of a condition.
if [[ condition ]]; then
instructions
fi
If the condition logically evaluates to true, the instructions between the then and fi keywords are then executed; otherwise, they are ignored.
Note:
It is possible to negate (or invert) the logical evaluation of a condition using the NOT logical operator
!.if [[ ! condition ]]; then instructions fiIn this case, if the condition logically evaluates to
false, the instructions between thethenandfikeywords are then executed; otherwise, they are ignored.
Example
Let's consider this script, that checks whether two strings are identical or different:
#!/bin/bash
if [[ $1 == $2 ]]; then
echo "Strings are identical"
fi
if [[ $1 != $2 ]]; then
echo "Strings are not identical"
fi
When executed, it will:
-
Check if the first positional argument
$1is identical to the second positional argument$2using the string equality operator==. -
Output the string "Strings are identical" if the condition logically evaluates to
true. -
Check if the first positional argument
$1is different from the second positional argument$2using the string inequality operator!=. -
Output the string "Strings are not identical" if the condition logically evaluates to
true.
Which will produce this output:
$ ./script.sh hello hello
Strings are identical
$ ./script.sh hello world
Strings are not identical
The else statement
The else statement, in conjunction with the if statement, is used to define a set of instructions that should be executed when the condition specified in the if statement logically evaluates to false.
if [[ condition ]]; then
instructions
else
instructions
fi
Note: It is common to say that a condition is met when it evaluates to
true, and unmet otherwise.
Example
Let's consider this script, that checks whether an integer is even or odd:
#!/bin/bash
remainder=$(($1 % 2))
if [[ $remainder -eq 0 ]]; then
echo "Number is even"
else
echo "Number is odd"
fi
Note: In programming, the modulo operator
%is used to calculate the remainder of the division of two integers. For example,10 % 5 = 0and10 % 3 = 1.
When executed, it will:
-
Check if the remainder of the division of the first positional argument
$1by2equals0. -
If it evaluates to
true, output the string "Number is even". -
Otherwise, output the string "Number is odd".
Which will produce this output:
$ ./script.sh 2
Number is even
$ ./script.sh 1
Number is odd
The elif statement
The elif statement (short for "else if"), in conjunction with the if-else statement, is used to test multiple conditions sequentially and execute different sets of instructions based on the first condition that logically evaluates to true.
if [[ condition ]]; then
instructions
elif [[ condition ]]; then
instructions
else
instructions
fi
Example
Let's consider this script, that checks whether a number is negative, positive, or zero:
#!/bin/bash
if [[ $1 -lt 0 ]]; then
echo "The number is negative"
elif [[ $1 -gt 0 ]]; then
echo "The number is positive"
else
echo "The number is zero"
fi
When executed, it will:
-
Check if the first positional argument
$1is less than0and output the string "The number is negative". -
Otherwise, check if the first positional argument
$1is greater than0and output the string "The number is positive". -
Otherwise, output the string "The number is zero".
Which will produce this output:
$ ./script.sh -1
The number is negative
$ ./script.sh 0
The number is zero
$ ./script.sh 1
The number is positive
The case statement
The case statement is used to evaluate a single variable or expression against a list of patterns or values, and execute different sets of instructions based on the match.
case variable in
pattern)
instructions
;;
pattern)
instructions
;;
*)
instructions
;;
esac
Where:
-
The double semicolon
;;indicates the end of a set of instructions. -
The wildcard
*is used as a fallback value that matches all other cases if none of the previous patterns are matched.
Note: The wildcard pattern is optional and must always be declared last.
Example
Let's consider this script, that translates numbers into week days:
#!/bin/bash
case $1 in
1)
echo "Monday"
;;
2)
echo "Tuesday"
;;
3)
echo "Wednesday"
;;
4)
echo "Thursday"
;;
5)
echo "Friday"
;;
6)
echo "Saturday"
;;
7)
echo "Sunday"
;;
*)
echo "Error"
;;
esac
When executed, it will:
-
Check if the first positional argument
$1matches any of the listed numbers from1to7and output the string corresponding to the day of the week. -
Otherwise, output the string "Error".
Which will produce this output:
$ ./script.sh 1
Monday
$ ./script.sh 3
Wednesday
$ ./script.sh 9
Error
Nesting conditional statements
A nested conditional statement is a statement placed inside another statement to create complex decision-making structures, allowing you to evaluate multiple conditions and execute different instructions based on these conditions.
Just like with any other instructions, each inner statement is executed based on the outcome of the outer statement, and so on.
Nesting if, elif, and else statements
When placing an if statement within another if statement, the second statement will only be evaluated if the first one evaluates to true.
if [[ condition ]]; then
if [[ condition ]]; then
instructions
fi
fi
When placing an if statement within another elif statement, the second statement will only be evaluated if the first one evaluates to false.
if [[ condition ]]; then
instructions
elif
if [[ condition ]]; then
instructions
fi
else
instructions
fi
When placing an if statement within another else statement, the second statement will only be evaluated if the first one evaluates to false.
if [[ condition ]]; then
instructions
else
if [[ condition ]]; then
instructions
fi
fi
Example
Let's consider this script, that outputs the type of motorbike based on its brand and model:
#!/bin/bash
brand=$1
model=$2
if [[ $brand == "Honda" ]]; then
if [[ $model == "CB500X" ]]; then
echo "Trail"
else
echo "Unknown model"
fi
else
echo "Unknown brand"
fi
When executed, it will:
-
Declare a variable named
brandand initialize it with the value of the 1st positional argument$1 -
Declare a variable named
modeland initialize it with the value of the 2nd positional argument$2 -
Check if the value of the
brandvariable is identical to the string"Honda"using the==operator, or output the string"Unknown brand"otherwise. -
Check if the value of the
modelvariable is identical to the string"CB500X"using the==operator and output the string"Trail", or output the string"Unknown model"otherwise.
Which will produce this output:
$ ./script.sh Honda CB500X
Trail
$ ./script.sh Honda SR1000RR
Unknown model
$ ./script.sh Yamaha MT09
Unknown brand
Nesting case statements
Nesting a case statement is quite similar to nesting other statements, as it will only be executed if the first variable matches the pattern it is defined under.
case variable in
pattern)
instructions
;;
pattern)
case variable in
pattern)
instructions
;;
esac
;;
*)
instructions
;;
esac
Example
Let's consider this script, that outputs the type of motorbike based on its brand and model:
#!/bin/bash
brand=$1
model=$2
case $brand in
Honda)
case $model in
CB500X)
echo "Trail"
;;
*)
echo "Unknown model"
;;
esac
;;
*)
echo "Unknown brand"
;;
esac
When executed, it will perform the same logic as the previous script and produce the same output.
Combining multiple conditions
It often happens that a set of instructions requires more than one condition in order to be executed.
Rather than unnecessarily nesting multiple if statements:
if [[ condition ]]; then
if [[ condition ]]; then
instructions
fi
fi
You can use the && (AND) and || (OR) logical operators to combine multiple if statements into a single one:
if [[ condition && condition ]]; then
instructions
fi
Note: Logical operators also work with the
elifstatement.
Example
Let's consider this script, that outputs whether a shop is open or closed:
#!/bin/bash
day=$1
time=$2
if [[ $day == "Monday" && $time -ge 6 ]]; then
echo "Open"
elif [[ $day == "Wednesday" || $day == "Friday" && $time -lt 11 ]]; then
echo "Open"
else
echo "Closed"
fi
When executed, it will:
-
Declare a variable named
dayand initialize it with the value of the 1st positional argument$1. -
Declare a variable named
timeand initialize it with the value of the 2nd positional argument$2. -
Check if the value of the
dayvariable equals the string"Monday"and the value of thetimevariable is greater than or equal to6. -
Output the string
"Open"if it evaluates totrue. -
Check if the value of the
dayvariable equals the string"Wednesday"or"Friday"and the value of thetimevariable is lesser than or equal to11. -
Output the string
"Open"if it evaluates totrue. -
Otherwise, output the string
"Closed".
Which will produce this output:
$ ./script.sh Monday 6
Open
$ ./script.sh Tuesday 6
Closed
$ ./script.sh Wednesday 9
Open
$ ./script.sh Friday 9
Open
$ ./script.sh Friday 11
Closed
🗒️ Summary
Here's a summary of what you've learned in this lesson:
-
A condition is an expression that when evaluated produces a boolean result.
-
The
==,!=,>, and<operators are used to compare strings. -
The
-eq,-ne,-lt,-le,-gt, and-geoperators are used to compare numbers. -
A control statement is a code structure used to manage the flow and logic of a script.
-
The
if,elif,else, andcaseare control statements that use conditions to selectively execute sets of instructions. -
The
!operator is used to negate a condition. -
Control statements can be nested to create complex decision-making structures.
-
Conditions can be combined using the
&&and||logical operators.
🤖 Projects
Here's a list of projects to apply what you've just learned:
- lb_calculator: Write a script that prints the result of an arithmetic operation.
Unlock the CLI & Scripting with Bash module
Learn how to gain advanced control over the OS and automate complex routine tasks prone to manual errors with the CLI and Bash scripting.
You get immediate access to:
- 34 focused lessons across the CLI and Bash
- 4 real-world projects with commented solutions
- Ongoing updates to this bundle
- Lifetime access to this bundle