How to Use Case Statement in Bash
Quick Answer: What Is a Case Statement?
A case statement is Bashâs version of a switch statementâit checks one variable against multiple patterns and runs different code for each match. Use it instead of chained if-else statements: case $var in pattern1) commands;; pattern2) commands;; esac
Quick Comparison: Case vs If-Else
| Aspect | Case Statement | If-Else |
|---|---|---|
| Readability | Excellent for many conditions | Better for 2-3 conditions |
| Performance | Very fast | Comparable |
| Complexity | Simple | Can get messy |
| Pattern matching | Built-in with wildcards | Requires extra work |
Bottom line: Use case for multiple values of one variable; use if-else for different variables or complex logic.
What is a Case Statement?
A case statement is Bashâs way of handling multiple conditions elegantly. Think of it like a more readable alternative to chained if-else statements. Instead of writing dozens of if [ $var = "value1" ]; then ... elif [ $var = "value2" ]; then ..., you can use case to match against multiple patterns in one clean structure.
This is particularly useful when youâre checking a single variable against many possible values. Itâs faster to read, easier to maintain, and less prone to typos.
Imagine youâre writing a script that takes a command as an argument: start, stop, or restart. With if-else, youâd write three separate conditions. With case, you write one clean block thatâs easy to understand at a glance. This is where case statements shineâwhen one variable determines what should happen.
Basic Syntax
The basic structure is straightforward once you know what each part does. Itâs case-sensitive, so the keyword is case (lowercase) at the start and esac (case backwards) at the endâa memorable mnemonic.
case $variable in
pattern1)
# Commands to run if $variable matches pattern1
;;
pattern2)
# Commands to run if $variable matches pattern2
;;
*)
# Default case if nothing matches
;;
esac
Hereâs whatâs happening: case starts the statement and $variable is what youâre checking. Each pattern ends with a closing parenthesis. The commands for that pattern follow. Critically, each pattern block must end with ;; (two semicolons)âthis is required syntax and is a common source of errors. The *) is a wildcard pattern that matches anythingâitâs your catch-all âdefaultâ case, similar to the else in if-else statements. The esac closes the entire case statement (itâs case spelled backwards, which is a nice memory aid).
When to Use Case Statements
Use case statements when:
- Youâre checking one variable against many values
- You have more than 3 possible values to check
- The conditions are distinct (not overlapping ranges)
- You want cleaner, more readable code
Use if-else when:
- Youâre checking different variables
- You have complex conditional logic (AND, OR combinations)
- You only need 2-3 simple checks
Simple Example: Script Menus
Hereâs a practical example where case statements shineâcreating a simple script menu. This is one of the most common uses for case statements:
#!/bin/bash
echo "What would you like to do?"
echo "1) Show disk usage"
echo "2) List running processes"
echo "3) Check system uptime"
echo "4) Exit"
read -p "Enter your choice (1-4): " choice
case $choice in
1)
echo "=== Disk Usage ==="
df -h
;;
2)
echo "=== Running Processes ==="
ps aux | head -10
;;
3)
echo "=== System Uptime ==="
uptime
;;
4)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid choice. Please select 1-4."
exit 1
;;
esac
When you run this script and select option 1, it displays disk usage. Select 3, and you get system uptime. Each case branch is labeled clearly and does one specific thing. Itâs much cleaner and more readable than writing a chain of if [ "$choice" = "1" ]; then ... elif [ "$choice" = "2" ]; then ... statements.
Notice the *) pattern at the endâit catches any input that doesnât match 1, 2, 3, or 4. This is good defensive programming. Without it, invalid input would silently do nothing, leaving users confused.
Pattern Matching with Wildcards
Case statements support wildcards, making them even more powerful. You can match against patterns, not just exact strings:
#!/bin/bash
read -p "Enter a filename: " filename
case $filename in
*.txt)
echo "This is a text file"
;;
*.sh)
echo "This is a shell script"
;;
*.md)
echo "This is a markdown file"
;;
*)
echo "Unknown file type"
;;
esac
If you enter âdocument.txtâ, it matches the first pattern. âscript.shâ matches the second. The *.txt pattern means âanything ending with .txtâ.
Multiple Patterns for One Action
Sometimes you want multiple patterns to trigger the same action. Separate them with pipes:
#!/bin/bash
read -p "Enter your favorite color: " color
case $color in
red|crimson|scarlet)
echo "You like red!"
;;
blue|azure|navy)
echo "You like blue!"
;;
green|lime|forest)
echo "You like green!"
;;
*)
echo "I'm not sure about that color."
;;
esac
This lets you group similar values together without repeating code.
Real-World Example: Service Manager
Hereâs a more substantial example - a script that starts, stops, or checks status of a service:
#!/bin/bash
SERVICE="nginx"
case "${1:-help}" in
start)
echo "Starting $SERVICE..."
systemctl start "$SERVICE"
echo "$SERVICE started successfully."
;;
stop)
echo "Stopping $SERVICE..."
systemctl stop "$SERVICE"
echo "$SERVICE stopped successfully."
;;
status)
echo "Checking $SERVICE status..."
systemctl status "$SERVICE"
;;
restart)
echo "Restarting $SERVICE..."
systemctl restart "$SERVICE"
echo "$SERVICE restarted successfully."
;;
*)
echo "Usage: $0 {start|stop|restart|status}"
echo ""
echo "Examples:"
echo " $0 start - Start the service"
echo " $0 stop - Stop the service"
echo " $0 restart - Restart the service"
echo " $0 status - Check service status"
exit 1
;;
esac
The "${1:-help}" syntax means âuse the first argument, or use âhelpâ as defaultâ. This script can be called as ./script.sh start or ./script.sh status.
Important Points to Remember
- Each case branch must end with
;;(two semicolons) - The
*)pattern acts as a default case (like else) - Patterns support wildcards:
*,?,[abc],[a-z] - Case statements are more efficient than chained if-else blocks
- You donât need parentheses around the variable -
case $var inworks fine - The
esackeyword closes the entire case statement (case backwards)
Common Mistakes to Avoid
Forgetting the closing semicolons:
case $var in
pattern1)
echo "This" # Missing ;;
pattern2)
echo "That"
;;
esac
This will cause a syntax error. Always include ;; at the end of each case.
Using multiple patterns without pipes:
# WRONG
case $color in
red scarlet) # This won't work
echo "Red!"
;;
esac
# RIGHT
case $color in
red|scarlet) # Use pipes between patterns
echo "Red!"
;;
esac
When to Use Case Statements
Use case statements when:
- Youâre checking one variable against many values
- You have more than 3 conditions
- The conditions are distinct and independent
- You want cleaner, more readable code
Use if-else when:
- Youâre checking different variables
- You have complex conditional logic
- You only need 2-3 simple checks
Summary
Case statements are a powerful tool for handling multiple conditions in a clean, readable way. Theyâre perfect for building menus, parsing command-line arguments, and routing logic based on a single variable. Master case statements and your shell scripts will be easier to read and maintain.