Skip to content

Case

The case statement in bash provides a way to compare a value against multiple patterns and execute different code blocks based on which pattern matches. It’s particularly useful for menu-driven scripts, argument parsing, and handling multiple conditions. This chapter covers the syntax, patterns, and practical applications for DevOps workflows.


case_basic.sh
#!/usr/bin/env bash
# Case statement syntax
case variable in
pattern1)
# commands for pattern1
;;
pattern2)
# commands for pattern2
;;
*)
# default case
;;
esac
case_example.sh
#!/usr/bin/env bash
read -p "Enter a day name: " day
case "$day" in
Monday)
echo "First day of work"
;;
Tuesday|Wednesday|Thursday)
echo "Mid-week day"
;;
Friday)
echo "Friday! Almost weekend"
;;
Saturday|Sunday)
echo "Weekend!"
;;
*)
echo "Invalid day"
;;
esac

multiple_patterns.sh
#!/usr/bin/env bash
# Multiple patterns with |
case "$1" in
start|Start|START)
echo "Starting..."
;;
stop|Stop|STOP)
echo "Stopping..."
;;
restart)
echo "Restarting..."
;;
*)
echo "Unknown command"
exit 1
;;
esac
wildcard_patterns.sh
#!/usr/bin/env bash
filename="document.pdf"
case "$filename" in
*.txt)
echo "Text file"
;;
*.pdf)
echo "PDF file"
;;
*.jpg|*.png|*.gif)
echo "Image file"
;;
*.sh)
echo "Shell script"
;;
*)
echo "Unknown file type"
;;
esac
character_classes.sh
#!/usr/bin/env bash
read -p "Enter a character: " char
case "$char" in
[a-z])
echo "Lowercase letter"
;;
[A-Z])
echo "Uppercase letter"
;;
[0-9])
echo "Digit"
;;
*)
echo "Other character"
;;
esac

parse_args.sh
#!/usr/bin/env bash
# Initialize default values
VERBOSE=false
FORCE=false
OUTPUT_FILE=""
# Parse command line arguments
while [ $# -gt 0 ]; do
case "$1" in
-h|--help)
echo "Usage: $0 [OPTIONS]"
echo "Options:"
echo " -h, --help Show this help message"
echo " -v, --verbose Enable verbose output"
echo " -f, --force Force operation"
echo " -o, --output Specify output file"
exit 0
;;
-v|--verbose)
VERBOSE=true
shift
;;
-f|--force)
FORCE=true
shift
;;
-o|--output)
OUTPUT_FILE="$2"
shift 2
;;
-*)
echo "Unknown option: $1"
exit 1
;;
*)
# Positional argument
echo "Processing file: $1"
shift
;;
esac
done
echo "Verbose: $VERBOSE"
echo "Force: $FORCE"
echo "Output: $OUTPUT_FILE"
env_select.sh
#!/usr/bin/env bash
# Set defaults based on environment
case "${ENVIRONMENT:-development}" in
production)
readonly DB_HOST="prod-db.example.com"
readonly DB_PORT="5432"
readonly LOG_LEVEL="warn"
readonly MAX_CONNECTIONS=200
readonly DEBUG=false
;;
staging)
readonly DB_HOST="staging-db.example.com"
readonly DB_PORT="5432"
readonly LOG_LEVEL="debug"
readonly MAX_CONNECTIONS=50
readonly DEBUG=true
;;
development|dev)
readonly DB_HOST="localhost"
readonly DB_PORT="5432"
readonly LOG_LEVEL="debug"
readonly MAX_CONNECTIONS=10
readonly DEBUG=true
;;
*)
echo "Invalid environment: $ENVIRONMENT"
echo "Valid environments: production, staging, development"
exit 1
;;
esac
echo "Environment: ${ENVIRONMENT:-development}"
echo "Database: $DB_HOST:$DB_PORT"
echo "Log Level: $LOG_LEVEL"
echo "Debug: $DEBUG"

menu.sh
#!/usr/bin/env bash
echo "================================"
echo " Server Management Menu"
echo "================================"
echo "1. Check server status"
echo "2. Start service"
echo "3. Stop service"
echo "4. View logs"
echo "5. Backup data"
echo "6. Exit"
echo "================================"
read -p "Enter your choice: " choice
case "$choice" in
1)
echo "Checking server status..."
systemctl status nginx
;;
2)
echo "Starting service..."
sudo systemctl start nginx
;;
3)
echo "Stopping service..."
sudo systemctl stop nginx
;;
4)
echo "Viewing logs..."
sudo journalctl -u nginx -n 50
;;
5)
echo "Backing up data..."
tar -czf backup_$(date +%Y%m%d).tar.gz /var/www
;;
6)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid choice"
exit 1
;;
esac
interactive_menu.sh
#!/usr/bin/env bash
show_menu() {
clear
echo "================================"
echo " Docker Management"
echo "================================"
echo "1. List containers"
echo "2. List images"
echo "3. Start container"
echo "4. Stop container"
echo "5. Remove container"
echo "6. View logs"
echo "7. Shell into container"
echo "0. Exit"
echo "================================"
}
while true; do
show_menu
read -p "Enter choice: " choice
case "$choice" in
1)
echo "Containers:"
docker ps -a
;;
2)
echo "Images:"
docker images
;;
3)
read -p "Container name: " container
docker start "$container"
;;
4)
read -p "Container name: " container
docker stop "$container"
;;
5)
read -p "Container name: " container
docker rm "$container"
;;
6)
read -p "Container name: " container
docker logs -f "$container"
;;
7)
read -p "Container name: " container
docker exec -it "$container" /bin/bash
;;
0)
echo "Goodbye!"
exit 0
;;
*)
echo "Invalid choice"
;;
esac
read -p "Press Enter to continue..."
done

service_controller.sh
#!/usr/bin/env bash
set -euo pipefail
# Check if service name provided
if [ $# -lt 2 ]; then
echo "Usage: $0 <action> <service>"
echo "Actions: start, stop, restart, status, enable, disable"
exit 1
fi
ACTION="$1"
SERVICE="$2"
case "$ACTION" in
start)
echo "Starting $SERVICE..."
sudo systemctl start "$SERVICE"
echo "$SERVICE started"
;;
stop)
echo "Stopping $SERVICE..."
sudo systemctl stop "$SERVICE"
echo "$SERVICE stopped"
;;
restart)
echo "Restarting $SERVICE..."
sudo systemctl restart "$SERVICE"
echo "$SERVICE restarted"
;;
status)
systemctl status "$SERVICE"
;;
enable)
echo "Enabling $SERVICE..."
sudo systemctl enable "$SERVICE"
echo "$SERVICE enabled"
;;
disable)
echo "Disabling $SERVICE..."
sudo systemctl disable "$SERVICE"
echo "$SERVICE disabled"
;;
*)
echo "Unknown action: $ACTION"
exit 1
;;
esac

file_type.sh
#!/usr/bin/env bash
detect_file_type() {
local file="$1"
if [ ! -e "$file" ]; then
echo "File does not exist"
return 1
fi
case "$(file -b --mime-type "$file")" in
text/plain)
echo "Text file"
;;
text/html)
echo "HTML file"
;;
image/*)
echo "Image file: $(file -b --mime-type "$file")"
;;
application/zip)
echo "ZIP archive"
;;
application/pdf)
echo "PDF document"
;;
application/json)
echo "JSON file"
;;
application/x-shellscript)
echo "Shell script"
;;
*)
echo "Other: $(file -b --mime-type "$file")"
;;
esac
}
# Usage
for file in "$@"; do
echo -n "$file: "
detect_file_type "$file"
done

signal_handler.sh
#!/usr/bin/env bash
# Handle signals
handle_signal() {
local signal="$1"
case "$signal" in
SIGTERM)
echo "Received SIGTERM, shutting down gracefully..."
cleanup
exit 0
;;
SIGINT)
echo "Received Ctrl+C, stopping..."
cleanup
exit 0
;;
SIGHUP)
echo "Received SIGHUP, reloading configuration..."
reload_config
;;
*)
echo "Received unknown signal: $signal"
;;
esac
}
cleanup() {
echo "Cleaning up..."
# Add cleanup tasks
rm -f /tmp/app.lock
}
reload_config() {
echo "Reloading configuration..."
# Add reload tasks
}
# Register signal handlers
trap 'handle_signal SIGTERM' TERM
trap 'handle_signal SIGINT' INT
trap 'handle_signal SIGHUP' HUP
echo "Script running... Press Ctrl+C to stop"
echo "PID: $$"
# Simulate long-running process
while true; do
sleep 1
done

exit_code_handler.sh
#!/usr/bin/env bash
handle_exit_code() {
local exit_code=$1
case "$exit_code" in
0)
echo "Success"
;;
1)
echo "General error"
;;
2)
echo "Misuse of shell command"
;;
126)
echo "Command not executable"
;;
127)
echo "Command not found"
;;
128)
echo "Invalid exit argument"
;;
130)
echo "Script terminated by Ctrl+C (SIGINT)"
;;
*)
echo "Unknown exit code: $exit_code"
;;
esac
}
# Example: Run command and handle exit code
grep "pattern" file.txt
handle_exit_code $?

advanced_patterns.sh
#!/usr/bin/env bash
# Extended pattern matching
shopt -s extglob
read -p "Enter filename: " filename
case "$filename" in
# Starts with backup
backup*)
echo "Backup file"
;;
# Ends with .log or .txt
*.log|*.txt)
echo "Log or text file"
;;
# Contains date pattern
*-202[0-9]-[0-9][0-9]-*)
echo "Dated file"
;;
# Exactly 3 characters
???)
echo "Three character filename"
;;
# Any other
*)
echo "Other file"
;;
esac
case_with_functions.sh
#!/usr/bin/env bash
deploy() {
local environment="$1"
local version="$2"
case "$environment" in
production)
echo "Deploying to PRODUCTION: $version"
confirm_deployment
;;
staging)
echo "Deploying to STAGING: $version"
;;
development|dev)
echo "Deploying to DEV: $version"
;;
*)
echo "Unknown environment: $environment"
return 1
;;
esac
}
confirm_deployment() {
local confirm
read -p "Confirm production deployment? (yes/no): " confirm
case "$confirm" in
yes|Yes|YES)
echo "Deploying..."
;;
*)
echo "Deployment cancelled"
exit 1
;;
esac
}
# Usage
deploy "$1" "$2"

deploy.sh
#!/usr/bin/env bash
set -euo pipefail
readonly SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
readonly SCRIPT_NAME="$(basename "$0")"
show_usage() {
cat << EOF
Usage: $SCRIPT_NAME [COMMAND] [OPTIONS]
Commands:
deploy <environment> <version> Deploy application
rollback <environment> Rollback to previous version
status Show deployment status
health Check application health
Options:
-h, --help Show this help message
-f, --force Force operation
-v, --verbose Verbose output
Examples:
$SCRIPT_NAME deploy production v1.2.3
$SCRIPT_NAME rollback staging
$SCRIPT_NAME status
EOF
}
log() {
echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*"
}
deploy() {
local environment="$1"
local version="$2"
log "Starting deployment: $environment $version"
case "$environment" in
production)
log "PRODUCTION deployment - extra checks"
check_production_prerequisites
;;
staging)
log "Staging deployment"
;;
development|dev)
log "Development deployment"
;;
*)
log "Invalid environment: $environment"
return 1
;;
esac
log "Pulling image..."
docker pull "myapp:$version"
log "Stopping old containers..."
docker-compose down
log "Starting new containers..."
docker-compose up -d
log "Deployment complete"
}
check_production_prerequisites() {
local confirm
read -p "This is a PRODUCTION deployment. Are you sure? (yes/no): " confirm
case "$confirm" in
yes|Yes|YES)
return 0
;;
*)
log "Deployment cancelled"
exit 1
;;
esac
}
rollback() {
local environment="$1"
log "Rolling back $environment"
docker-compose down
docker-compose up -d
}
status() {
log "Checking status..."
docker-compose ps
}
health() {
log "Checking health..."
curl -f http://localhost:8080/health || exit 1
}
# Main
COMMAND="${1:-}"
case "$COMMAND" in
deploy)
deploy "$2" "$3"
;;
rollback)
rollback "$2"
;;
status)
status
;;
health)
health
;;
-h|--help)
show_usage
;;
*)
show_usage
exit 1
;;
esac

In this chapter, you learned about:

  • ✅ Basic case statement syntax
  • ✅ Pattern matching with wildcards
  • ✅ Multiple patterns with |
  • ✅ Character classes
  • ✅ Command-line argument parsing
  • ✅ Menu systems
  • ✅ Service management scripts
  • ✅ File type detection
  • ✅ Signal handling
  • ✅ Exit code handling
  • ✅ Advanced patterns
  • ✅ Combining case with functions
  • ✅ Real-world DevOps examples

  1. Write a script that converts number grades to letter grades using case
  2. Create a script that processes command-line flags using case
  3. Write a menu-driven calculator using case
  1. Create a service management script using case
  2. Write a file type detection script
  3. Implement a deployment script with environment selection
  1. Create a complete CLI tool with multiple commands
  2. Implement signal handling with case
  3. Build an interactive menu system with case

Continue to the next chapter to learn about loops.


Previous Chapter: Conditionals Next Chapter: Loops