A basic Bash scripting need for making decisions about certain conditions is using the bash if elif else statement with examples. The conditional logic in scripts makes a static shell script into an active-thinking reactive automation of real server tasks. As either a new scripting user creating their first script or as a seasoned sysadmin creating a validation tool to deploy servers, you will be utilizing conditional logic with if else and elif in Bash commands in daily.
Why This Topic Matters
Most tutorials only show syntax and move on. But in real-world Linux environments, conditional logic is used for:
- Checking if a service is running before restarting it
- Validating environment variables before a deployment runs
- Writing backup scripts that skip missing directories gracefully
- Building health-check scripts for Ubuntu and Rocky Linux servers
This guide covers beginner syntax through intermediate real-world usage, including the bracket confusion nobody else explains.
Before diving in, if you are new to scripting, take a look at what Bash scripting is and how it works on Linux to get the foundation in place first.
Bash if elif else Statement - Starting With One Condition
The simplest form of a Bash conditional checks one condition and runs a block of code only when it is true. Nothing runs when the condition is false. The structure follows a clear open-and-close pattern using if and fi (which is just if spelled backwards).
LinuxTeck.com
age=25
if [ $age -gt 18 ]; then
echo "Access granted."
fi
Common Mistake: Missing Spaces Around Brackets
This is the most common beginner error. Bash requires spaces inside the brackets, otherwise the script fails with a syntax error.
Wrong: if [$age -gt 18]
Right: if [ $age -gt 18 ]
Always leave a space after [ and before ].
How it Works
The [ ] is actually a command called test. When you write if [ condition ], Bash runs the test command and checks the exit code. Exit code 0 means true, anything else means false. Understanding this helps a lot when you start debugging scripts. Learn more about Bash exit codes and error handling to build on this concept.
The if-else Statement - Handling Two Outcomes
When you need the script to do something when the condition is true and something different when it is false, you add else. This covers most real binary decisions: file exists or not, service running or not, user is root or not.
LinuxTeck.com
# Check if the user is root
if [ $(id -u) -eq 0 ]; then
echo "You are running as root. Proceeding..."
else
echo "This script requires root privileges. Use sudo."
exit 1
fi
This kind of root-check is something you will see in almost every serious Linux automation script. It is a real pattern used in production scripts on both Ubuntu and Rocky Linux. For more practical patterns like this, check out how to write interactive shell scripts in Linux.
Tip: Compact One-Liner Style
You can write a short if-else on one line using semicolons. Useful for quick checks inside larger scripts:
[ -f /etc/passwd ] && echo "File exists" || echo "Not found"
But for anything beyond simple checks, the full multi-line format is much easier to read and maintain.
The elif Statement - Handling Multiple Conditions
When two outcomes are not enough, elif lets you chain multiple conditions together. Bash evaluates them in order from top to bottom and stops as soon as one condition is true. Only one block ever runs.
LinuxTeck.com
score=72
if [ $score -ge 90 ]; then
echo "Grade: A"
elif [ $score -ge 75 ]; then
echo "Grade: B"
elif [ $score -ge 60 ]; then
echo "Grade: C"
else
echo "Grade: F - Please retry."
fi
How elif Works Internally
Bash checks the first if condition. If it is false, it moves to the first elif. If that is false, it moves to the next elif, and so on. When it finally hits a true condition, it runs that block and skips everything else. The else at the end is optional and acts as the fallback when all other conditions are false.
Using bash elif multiple conditions is common in server health checks, log-level routers, and deployment scripts. You can add as many elif blocks as you need. For writing more complex automation, see Linux Bash scripting automation guide for 2026.
[ ] vs [[ ]] - The Confusion Nobody Fully Explains
This is the number one source of bugs for people moving from beginner to intermediate scripting. Almost no tutorial explains the difference properly. Here is exactly what you need to know about bash conditional expressions [[ ]] vs [ ].
| Feature | Single Bracket [ ] | Double Bracket [[ ]] |
|---|---|---|
| Standard | POSIX sh works in all shells | Bash-specific only in Bash 2.02+ |
| Word splitting | Can break on unquoted variables | Safe no word splitting inside |
| Regex matching | Not supported | Supported with =~ |
| Pattern matching | Not supported | Supported with == |
| AND / OR operators | -a and -o |
&& and || (cleaner) |
| Unquoted empty variable | Breaks on string comparison "unary operator expected" | Safe handles empty strings |
| Use case | Legacy or POSIX-compatible (sh) scripts | Modern Bash scripts (recommended) |
Here is a practical example showing why the difference actually matters:
LinuxTeck.com
username=""
# SINGLE BRACKET - BREAKS when variable is empty
if [ $username = "admin" ]; then
echo "Hello admin"
fi
# Error: [: =: unary operator expected
# DOUBLE BRACKET - SAFE with empty variables
if [[ $username = "admin" ]]; then
echo "Hello admin"
fi
# No error - evaluates cleanly as false
Recommendation
If your script starts with #!/bin/bash, use [[ ]] for everything except when you specifically need POSIX sh compatibility. It is safer, cleaner, and supports regex. Always use #!/bin/bash explicitly never rely on the system default shell being Bash.
Ubuntu-Specific Warning
On Ubuntu 22.04 and 24.04, /bin/sh points to dash, not Bash. If you run a script with sh script.sh or use #!/bin/sh, double brackets [[ ]] will throw a syntax error because dash does not support them.
Fix: Always use #!/bin/bash as your shebang and run with bash script.sh.
Comparison Operators Integer, String, and File Tests
Bash conditions are only as powerful as your knowledge of the operators available. This is the full reference most guides skip over. Understanding all available operators is what lets you write real-world scripts instead of toy examples.
Integer Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
-eq |
Equal to | [ $a -eq $b ] |
-ne |
Not equal to | [ $a -ne $b ] |
-gt |
Greater than | [ $a -gt $b ] |
-lt |
Less than | [ $a -lt $b ] |
-ge |
Greater than or equal | [ $a -ge $b ] |
-le |
Less than or equal | [ $a -le $b ] |
String Comparison Operators
| Operator | Meaning | Example |
|---|---|---|
= |
Strings are equal | [ "$a" = "$b" ] |
== |
Same as = (Bash only) | [[ $a == $b ]] |
!= |
Strings are not equal | [ "$a" != "$b" ] |
-z |
String is empty (zero length) | [ -z "$var" ] |
-n |
String is not empty | [ -n "$var" ] |
=~ |
Regex match (double bracket only) | [[ $var =~ ^[0-9]+$ ]] |
File and Directory Test Operators
| Operator | Meaning | Practical Use |
|---|---|---|
-e |
File or directory exists | Pre-deployment config checks |
-f |
Regular file exists | Log file validators, backup scripts |
-d |
Directory exists | Check backup target before writing |
-r |
File is readable | Validate config before parsing |
-w |
File is writable | Check write permission before output |
-x |
File is executable | Verify script permissions |
-s |
File exists and is not empty | Log rotation, backup integrity checks |
-L or -h |
File is a symbolic link | Symlink auditing scripts |
-nt |
File is newer than another | Incremental backup logic |
-ot |
File is older than another | Cache invalidation scripts |
Here is a file test in a real backup validation context on Ubuntu or Rocky Linux:
LinuxTeck.com
BACKUP_DIR="/mnt/backup"
LOG_FILE="/var/log/backup.log"
# Use '!' to check if the directory does NOT exist
if [ ! -d "$BACKUP_DIR" ]; then
echo "Backup directory does not exist. Creating it..."
mkdir -p "$BACKUP_DIR"
# Check if the directory is NOT writable
elif [ ! -w "$BACKUP_DIR" ]; then
echo "No write permission to $BACKUP_DIR. Exiting."
exit 1
else
echo "Backup directory is ready."
fi
if [ -f "$LOG_FILE" ] && [ -s "$LOG_FILE" ]; then
echo "Log file exists and has content."
else
echo "Log file is empty or missing. Starting fresh."
fi
For a deeper look at how backup scripts are built for real servers, see the full automatic Linux backup script guide on LinuxTeck.
Pattern Matching and Regex Inside if Statements
This is one of the most powerful features of the double-bracket syntax. Using =~ inside [[ ]], you can match a variable against a regular expression directly inside your condition. No need to pipe through grep or sed.
Validate an IP Address in a Script
LinuxTeck.com
IP="192.168.1.105"
IP_REGEX="^([0-9]{1,3}\.){3}[0-9]{1,3}$"
if [[ $IP =~ $IP_REGEX ]]; then
echo "Valid IP address: $IP"
else
echo "Invalid IP address format."
fi
Validate User Input is a Number
LinuxTeck.com
echo "Enter a port number:"
read PORT
if [[ $PORT =~ ^[0-9]+$ ]]; then
if [ $PORT -ge 1 ] && [ $PORT -le 65535 ]; then
echo "Valid port: $PORT"
else
echo "Port out of range (1-65535)."
fi
else
echo "Error: Not a number. Please enter digits only."
fi
Note: Do Not Quote the Regex Variable
When using =~, store your regex in a variable and do NOT quote it on the right side of =~. Quoting the regex forces Bash to treat it as a literal string instead of a pattern, which breaks the match. Use [[ $var =~ $REGEX ]] not [[ $var =~ "$REGEX" ]].
Pattern matching with regex in Bash conditions is especially useful in combination with the sed command in Linux when processing log files or config files line by line.
Real DevOps Automation Examples with if-elif-else
This is where everything comes together. Here are scripts that you can actually use on a real Ubuntu 22.04/24.04 or Rocky Linux 9 server. These are the kinds of scripts that run in production CI/CD pipelines and cron jobs.
Example 1 : Check if a Service is Running (Ubuntu / Rocky Linux)
LinuxTeck.com
# Works on Ubuntu 22.04/24.04 and Rocky Linux 9
SERVICE="nginx"
if systemctl is-active --quiet "$SERVICE"; then
echo "$SERVICE is running. No action needed."
elif systemctl is-enabled --quiet "$SERVICE"; then
echo "$SERVICE is enabled but stopped. Attempting restart..."
systemctl start "$SERVICE"
else
echo "$SERVICE is not installed or not enabled."
exit 1
fi
Example 2 : Validate Environment Variables Before Deployment
LinuxTeck.com
# Pre-deployment environment variable check
required_vars=("DB_HOST" "DB_USER" "DB_PASS" "APP_ENV")
missing=0
for var in "${required_vars[@]}"; do
if [[ -z "${!var}" ]]; then
echo "MISSING: $var is not set."
missing=1
else
echo "OK: $var is set."
fi
done
if [ $missing -eq 1 ]; then
echo "Deployment aborted. Set all required variables."
exit 1
else
echo "All variables OK. Starting deployment..."
fi
Example 3 : Server Health Check for Ubuntu or Rocky Linux 9
LinuxTeck.com
# Server Health Check - Ubuntu 22.04/24.04 + Rocky Linux 9
DISK_USAGE=$(df / | awk "NR==2 {print $5}" | tr -d "%")
CPU_LOAD=$(uptime | awk -F"load average:" "{print $2}" | cut -d"," -f1 | tr -d " ")
echo "--- Server Health Report ---"
if [ "$DISK_USAGE" -ge 90 ]; then
echo "[CRITICAL] Disk usage is at ${DISK_USAGE}%"
elif [ "$DISK_USAGE" -ge 75 ]; then
echo "[WARNING] Disk usage is at ${DISK_USAGE}%"
else
echo "[OK] Disk usage is at ${DISK_USAGE}%"
fi
if (( $(echo "$CPU_LOAD > 4.0" | bc -l) )); then
echo "[CRITICAL] CPU load is high: $CPU_LOAD"
elif (( $(echo "$CPU_LOAD > 2.0" | bc -l) )); then
echo "[WARNING] CPU load is elevated: $CPU_LOAD"
else
echo "[OK] CPU load is normal: $CPU_LOAD"
fi
Scripts like these are the foundation of proper server monitoring. Pair them with the best Linux monitoring tools to build a complete observability setup.
Distro-Specific Notes : Ubuntu 22.04/24.04 and Rocky Linux 9
No tutorial on this topic covers distro differences. Here is what you actually need to know when writing if-else Bash scripts across different Linux distributions.
Ubuntu 22.04 / 24.04
Important: Default Shell is Dash, Not Bash
Ubuntu's /bin/sh symlinks to dash, a minimal POSIX shell that does not support [[ ]], =~, or many Bash-specific features. This is a common source of scripts that work when run directly but fail when called with sh.
Always use: #!/bin/bash at the top of your script
Always run with: bash script.sh or chmod +x script.sh && ./script.sh
Never use: sh script.sh if your script uses Bash-specific features
Check which shell /bin/sh points to on your Ubuntu system:
LinuxTeck.com
Rocky Linux 9 / RHEL 9
Rocky Linux 9 Shell Behavior
On Rocky Linux 9 and RHEL 9, /bin/sh symlinks to bash, so scripts are slightly more forgiving. However, it is still best practice to explicitly declare #!/bin/bash rather than rely on this.
On Rocky Linux 9, firewalld is active by default. If your if-else scripts interact with network services, you may need to allow traffic through firewalld first. See the firewall-cmd command guide for common patterns.
For a full comparison of how Ubuntu and RHEL/Rocky Linux differ as server platforms, check out RHEL vs Ubuntu Server to understand the broader environment your scripts will run in.
Common Errors and How to Fix Them
This section covers the actual error messages you will encounter when writing bash if else script examples on Linux. These are real errors with real fixes.
Error 1: "unary operator expected"
Cause
This happens when a variable is empty and you use it unquoted inside single brackets.
Bad: if [ $name = "admin" ] when $name is empty, Bash sees if [ = "admin" ] which is invalid.
Fix: Always quote your string variables: if [ "$name" = "admin" ] or switch to [[ ]].
Error 2: "integer expression expected"
Cause
This happens when you use integer operators like -eq, -gt, or -lt on a variable that contains a string or is empty.
Bad: if [ "$count" -gt 5 ] when $count is empty or has a value like "none".
Fix: Validate that the variable is a number first using [[ $count =~ ^[0-9]+$ ]] before doing the integer comparison.
Error 3: "command not found" or syntax error near unexpected token
Cause
Usually happens when running a Bash script with sh instead of bash, or when using Windows line endings (CRLF) in a script created on Windows.
Fix for shell issue: Use bash script.sh or add #!/bin/bash and run ./script.sh.
Fix for Windows line endings: sed -i 's/\r//' script.sh
Error 4: Using = vs == vs -eq
Which Operator to Use When
= and == are for string comparison. -eq is for integer comparison. Mixing them causes errors or unexpected behavior:
[ "$str" = "hello" ]correct string comparison[[ $str == "hello" ]]correct string comparison (Bash)[ $num -eq 5 ]correct integer comparison[ $num = 5 ]works but compares as strings, avoid this
Error 5: No Space Around Brackets
LinuxTeck.com
if [$var -eq 1]; then
# Right - spaces are required
if [ $var -eq 1 ]; then
# Also right - double bracket
if [[ $var -eq 1 ]]; then
For a broader look at scripting best practices that prevent these errors before they happen, see how to set up your shell scripting environment properly.
Quick Reference Cheat Sheet : Bash if/elif/else
Bookmark this section. It has every operator and syntax pattern you need for writing Bash conditional statements, in one place.
Syntax Patterns
LinuxTeck.com
if [ condition ]; then
commands
fi
# Pattern 2: if-else
if [ condition ]; then
commands
else
commands
fi
# Pattern 3: if-elif-else
if [ condition1 ]; then
commands
elif [ condition2 ]; then
commands
else
commands
fi
# Pattern 4: Nested if
if [ condition1 ]; then
if [ condition2 ]; then
commands
fi
fi
# Pattern 5: AND / OR
if [[ $a -gt 0 && $b -gt 0 ]]; then
commands
fi
if [[ $a -eq 1 || $b -eq 1 ]]; then
commands
fi
For a complete shell scripting cheat sheet covering loops, functions, and more, see the Linux shell scripting command cheat sheet.
Frequently Asked Questions
What is elif in Bash scripting?
elif stands for "else if" and is the Bash keyword for adding multiple conditions in a chain. When the first if condition is false, Bash checks the elif condition. You can stack as many elif blocks as you need. Bash evaluates them in order and runs only the first block whose condition is true.
It is equivalent to else if in languages like Python or JavaScript but written as one word in Bash.
How do I use if else in a Bash shell script step by step?
Here is the basic process: start with #!/bin/bash, write your condition inside [ ] or [[ ]] after the if keyword, add then, write the commands for when true, add else, write the commands for when false, and close with fi. Make the script executable with chmod +x script.sh and run it with ./script.sh. For a full step-by-step guide see the Bash Hello World script tutorial.
What is the difference between [ ] and [[ ]] in Bash if statements?
[ ] is the POSIX test command and works in all shells. [[ ]] is Bash-specific and safer because it handles empty variables without errors, supports regex with =~, and allows && and || directly inside the brackets. For scripts that only need to run in Bash, prefer [[ ]] in almost all cases.
Why does my Bash if statement work in the terminal but fail in a script?
The most common cause is that the script is running under a different shell than your terminal. On Ubuntu, if you run sh script.sh, it uses dash instead of Bash. Dash does not support [[ ]] or Bash-specific features. Make sure your script has #!/bin/bash on the first line and run it with bash script.sh or ./script.sh after making it executable. Windows line endings in the script file can also cause this problem.
Can I use multiple conditions in a single if statement in Bash?
Yes. Use && for AND and || for OR inside [[ ]]. For example: if [[ $a -gt 0 && $b -gt 0 ]]; then runs only if both conditions are true. With single brackets you use -a for AND and -o for OR, but these are deprecated in favor of the cleaner && and || syntax inside double brackets.
How do I check if a file exists in a Bash if statement?
Use the -f flag for regular files or -d for directories: if [ -f "/etc/nginx/nginx.conf" ]; then echo "Config exists"; fi. For more file test options including checking permissions and whether a file is empty, see the file test operators table in section 05 of this guide.
What does "unary operator expected" mean in Bash?
It means a variable inside [ ] was empty, so Bash got an incomplete expression. For example, if [ $name = "admin" ] when $name is empty becomes if [ = "admin" ], which is invalid. Fix it by quoting the variable: if [ "$name" = "admin" ], or by switching to double brackets which handle empty variables safely: if [[ $name = "admin" ]].
Summary
Understanding bash if elif else statements with examples is the foundation of writing scripts that actually work in real server environments. From basic syntax to file tests, regex matching inside conditions, and real DevOps automation patterns, this guide has covered everything you need to move from beginner to confident intermediate scripter. The key takeaway is to use [[ ]] for modern Bash scripts, always declare #!/bin/bash, and quote your variables to avoid the most common runtime errors.
For your next step, learn how to handle failures gracefully with Bash exit codes and error handling (Part 5 of 34) on LinuxTeck.
Related Articles