CIS120Linux Fundementals
Conditional Statements (if, else, elseif)
Conditional Expressions
Conditional expressions in Linux are used in shell scripting to evaluate conditions and control the flow of execution. They are typically used in conditional statements (if, else, elseif), while loops, and other control structures to make decisions based on comparisons, file attributes, or logical operations.
In Linux shell scripting, [ ]
(or test
) and [[ ]]
are used to evaluate conditional expressions, but [[ ]]
provides additional functionality and is preferred in modern Bash scripting. Here's a breakdown of the differences:
Basic Differences
Feature | [ ] (Single Brackets) |
[[ ]] (Double Brackets) |
---|---|---|
Shell Built-in | Yes (but also a standalone test command) |
Yes (Bash/Ksh specific) |
Operators | Supports basic test conditions | Supports additional operators |
String Comparisons | Requires escaping > and < |
No escaping needed |
Logical Operators | Uses -a (AND), -o (OR) |
Uses && (AND), ` |
Pattern Matching | No (except with expr ) |
Supports =~ for regex |
Variable Expansion | May cause word splitting and globbing | Prevents word splitting |
Examples
Example 1: String Comparison
Using [ ]
(requires quoting variables to avoid errors if empty):
VAR="hello"
if [ "$VAR" == "hello" ]; then
echo "Matched"
fi
Using [[ ]]
generally safer, and quoting is not required in most cases. However, quotes are needed if the variable may be empty or contain spaces, especially when using string comparisons or pattern matching. NOTE: An empty variable won't cause a syntax error, while with [ ... ]
, it will if quotes are missing. While quoting is always a good practice, [[ ... ]]
is more forgiving.
VAR="hello"
if [[ $VAR == "hello" ]]; then
echo "Matched"
fi
Example 2: Numeric Comparison
Both work the same for numbers:
NUM=10
if [ "$NUM" -gt 5 ]; then
echo "Greater than 5"
fi
NUM=10
if [[ $NUM -gt 5 ]]; then
echo "Greater than 5"
fi
Example 3: File Existence Check
Both work the same:
if [ -f "/etc/passwd" ]; then
echo "File exists"
fi
if [[ -f "/etc/passwd" ]]; then
echo "File exists"
fi
Example 4: Logical AND/OR
[ ]
requires -a
and -o
, which can be problematic:
if [ -f "/etc/passwd" -a -r "/etc/passwd" ]; then
echo "File exists and is readable"
fi
[[ ]]
allows &&
and ||
, making it clearer:
if [[ -f "/etc/passwd" && -r "/etc/passwd" ]]; then
echo "File exists and is readable"
fi
Example 5: String Comparison (<
, >
)
With [ ]
, <
and >
must be escaped:
if [ "apple" \< "banana" ]; then
echo "Apple comes before banana"
fi
With [[ ]]
, no escaping is needed:
if [[ "apple" < "banana" ]]; then
echo "Apple comes before banana"
fi
Example 6: Regex Matching (Only with [[ ]]
)
[[ ]]
supports regex with =~
:
VAR="hello123"
if [[ $VAR =~ ^hello[[0-9]+$ ]]; then
echo "Matches regex pattern"
fi
This would not work with [ ]
since it lacks regex support.
Summing Up [ ] and [[ ]]
The [ ]
conditional expression is a Bash/Ksh-specific feature and is not available in POSIX-compliant shells like /bin/sh
. This means that scripts intended to run in environments where only POSIX sh
is available, such as older Unix systems, minimal Linux distributions, or embedded systems, may not support [[ ]]
. Instead, they require the use of [ ]
(or test
). Additionally, if a script explicitly specifies #!/bin/sh
as its interpreter, it may not support [[ ]]
, depending on the system’s shell implementation. To ensure portability, scripts intended for generic POSIX environments should avoid [[ ]]
and use [ ]
instead.
- Use
[[ ]]
when possible in Bash scripts because it's safer, more readable, and feature-rich. - Use
[ ]
when writing portable scripts that may run in/bin/sh
, where[[ ]]
isn't available.
If, Else and ElseIf Statments
In Linux shell scripting, if, else, and elif (else if) statements are used to create conditional logic, allowing scripts to execute different commands based on specific conditions. The if statement evaluates a condition, and if it is true, the corresponding block of code executes. If the condition is false, an else statement can provide an alternative execution path. The elif statement allows for multiple conditions to be checked sequentially, executing the first matching condition and skipping the rest. These statements help control the flow of execution by making decisions dynamically, which is essential for automation, error handling, and interactive scripts.
Let's take a look at how we use if
, else
and else if
statements.
Basic if Statement
A basic if
statement in Bash follows this syntax:
if [[ condition ]]; then
# Commands to execute if condition is true
fi
In this example, the script checks if the variable number
is greater than 3 and prints a message if the condition is true.
#!/bin/bash
number=5
if [[ $number -gt 3 ]]; then
echo "The number is greater than 3"
fi
if-else Statement
An if-else
statement allows you to execute different commands based on whether the condition is true or false.
if [[ condition ]]; then
# Commands to execute if condition is true
else
# Commands to execute if condition is false
fi
In this example, the script prints a different message based on whether the number
is greater than 3.
#!/bin/bash
number=2
if [[ $number -gt 3 ]]; then
echo "The number is greater than 3"
else
echo "The number is not greater than 3"
fi
Multiple if-else Statements (elif)
You can use multiple if-else
statements to test several conditions.
if [[ condition1 ]]; then
# Commands to execute if condition1 is true
elif [[ condition2 ]]; then
# Commands to execute if condition2 is true
else
# Commands to execute if neither condition1 nor condition2 is true
fi
In this example, the script checks multiple conditions and prints the appropriate message based on the value of number
.
#!/bin/bash
number=3
if [[ $number -gt 3 ]]; then
echo "The number is greater than 3"
elif [[ $number -eq 3 ]]; then
echo "The number is equal to 3"
else
echo "The number is less than 3"
fi
Nested if-else Statements
Nested if-else
statements are if-else
statements within another if-else
statement.
In this example, the script first checks if the number
is greater than 0. If true, it then checks if the number
is less than 10 and prints the appropriate message based on the nested conditions.
#!/bin/bash
number=4
if [[ $number -gt 0 ]]; then
if [[ $number -lt 10 ]]; then
echo "The number is between 1 and 9"
else
echo "The number is 10 or greater"
fi
else
echo "The number is zero or negative"
fi
Comparisons in Bash
In Bash, you can use various comparison operators to test conditions.
Equality (==
):
if [[ "$str1" == "$str2" ]]; then
echo "Strings are equal"
fi
Regex Match (=~
):
if [[ "$str" =~ ^[0-9]+$ ]]; then
echo "String contains only digits"
fi
Inequality (!=
):
if [[ "$str1" != "$str2" ]]; then
echo "Strings are not equal"
fi
Numeric Comparisons:
Greater than (-gt
):
if [[ $num1 -gt $num2 ]]; then
echo "$num1 is greater than $num2"
fi
Less than (-lt
):
if [[ $num1 -lt $num2 ]]; then
echo "$num1 is less than $num2"
fi
Greater than or equal to (-ge
):
if [[ $num1 -ge $num2 ]]; then
echo "$num1 is greater than or equal to $num2"
fi
Less than or equal to (-le
):
if [[ $num1 -le $num2 ]]; then
echo "$num1 is less than or equal to $num2"
fi
Equal to (-eq
):
if [[ $num1 -eq $num2 ]]; then
echo "$num1 is equal to $num2"
fi
Not equal to (-ne
):
if [[ $num1 -ne $num2 ]]; then
echo "$num1 is not equal to $num2"
fi
Checks if a file exits using (-f
). If so then outputs the contents, if not then says "No file found".
if [[ -f file.txt ]]; then
echo "File contents:"
cat file.txt
else
echo "No file found."
fi
Logical Operators
You can also use logical operators to combine multiple conditions.
AND (&&
):
if [[ $num -gt 0 ]] && [[ $num -lt 10 ]]; then
echo "The number is between 1 and 9"
fi
OR (||
):
if [[ $num -eq 0 ]] || [[ $num -eq 10 ]]; then
echo "The number is 0 or 10"
fi
String Comparisons
String comparisons in Bash can also be performed using various operators:
Check if a string is empty (-z
):
if [[ -z "$str" ]]; then
echo "String is empty"
fi
Check if a string is not empty (-n
):
if [[ -n "$str" ]]; then
echo "String is not empty"
fi
Check if a string starts with a specific substring:
if [[ "$str" == prefix* ]]; then
echo "String starts with 'prefix'"
fi
Comparison Operators Table
Comparison | Operator | Example | Description |
---|---|---|---|
Equality | == |
[[ "$str1" == "$str2" ]] |
Strings are equal |
Regex Match | =~ |
[[ "$str" =~ ^[0-9]+$ ]] |
String matches regex |
Inequality | != |
[[ "$str1" != "$str2" ]] |
Strings are not equal |
Numeric Greater | -gt |
[[ $num1 -gt $num2 ]] |
num1 is greater than num2 |
Numeric Less | -lt |
[[ $num1 -lt $num2 ]] |
num1 is less than num2 |
Numeric Greater or Equal | -ge |
[[ $num1 -ge $num2 ]] |
num1 is greater than or equal to num2 |
Numeric Less or Equal | -le |
[[ $num1 -le $num2 ]] |
num1 is less than or equal to num2 |
Numeric Equal | -eq |
[[ $num1 -eq $num2 ]] |
num1 is equal to num2 |
Numeric Not Equal | -ne |
[[ $num1 -ne $num2 ]] |
num1 is not equal to num2 |
String Empty | -z |
[[ -z "$str" ]] |
String is empty |
String Not Empty | -n |
[[ -n "$str" ]] |
String is not empty |
String Starts With | == prefix* |
[[ "$str" == prefix* ]] |
String starts with 'prefix' |
Checks if file exits | -f |
[[ -f file.txt ]] |
Checks if file.txt exits |
Logical AND | && |
[[ $num -gt 0 ]] && [[ $num -lt 10 ]] |
Both conditions are true |
Logical OR | || |
[[ $num -gt 10 ]] || [[ $num -lt 5 ]] |
Only one condition needs to be true for this condtion to evaluate as true |
Summary
Bash provides powerful constructs to handle conditional execution using if
, if-else
, and nested if-else
statements. Various comparison operators like ==
, =~
, !=
, -gt
, -lt
, and logical operators &&
and ||
help in forming complex conditions. Understanding these constructs and operators allows you to write more efficient and readable Bash scripts.