case Statement

Multi-way conditional construct for pattern matching and selective execution in bash scripting.

Syntax

case EXPRESSION in PATTERN1) COMMANDS ;; PATTERN2|PATTERN3) COMMANDS ;; *) DEFAULT_COMMANDS ;; esac

The case statement compares an expression against patterns and executes matching code blocks.

Basic Usage

Simple case statement

#!/bin/bash read -p "Enter a day (1-7): " day case $day in 1) echo "Monday" ;; 2) echo "Tuesday" ;; 3) echo "Wednesday" ;; 4) echo "Thursday" ;; 5) echo "Friday" ;; 6) echo "Saturday" ;; 7) echo "Sunday" ;; *) echo "Invalid day" ;; esac

Basic case statement with numeric patterns

String matching

#!/bin/bash read -p "Enter your choice (yes/no): " choice case $choice in yes|y|YES|Y) echo "You chose yes" ;; no|n|NO|N) echo "You chose no" ;; *) echo "Please enter yes or no" ;; esac

String pattern matching with multiple options

Command line argument processing

#!/bin/bash case $1 in start) echo "Starting service..." ;; stop) echo "Stopping service..." ;; restart) echo "Restarting service..." ;; status) echo "Checking service status..." ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac

Process command line arguments

Pattern Matching

Wildcard patterns

#!/bin/bash filename="$1" case $filename in *.txt) echo "Text file" ;; *.jpg|*.jpeg|*.png|*.gif) echo "Image file" ;; *.mp3|*.wav|*.flac) echo "Audio file" ;; *.mp4|*.avi|*.mkv) echo "Video file" ;; *.tar.gz|*.tgz) echo "Compressed archive" ;; *) echo "Unknown file type" ;; esac

Use wildcards for pattern matching

Character classes and ranges

#!/bin/bash read -p "Enter a character: " char case $char in [a-z]) echo "Lowercase letter" ;; [A-Z]) echo "Uppercase letter" ;; [0-9]) echo "Digit" ;; [!a-zA-Z0-9]) echo "Special character" ;; *) echo "Multiple characters or empty" ;; esac

Character classes and ranges in patterns

Complex patterns

#!/bin/bash input="$1" case $input in [Yy][Ee][Ss]) echo "Affirmative response" ;; [Nn][Oo]) echo "Negative response" ;; [0-9][0-9][0-9]) echo "Three-digit number" ;; +([0-9])) echo "Positive integer" ;; -([0-9])) echo "Negative integer" ;; *@(gmail|yahoo|hotmail).com) echo "Common email provider" ;; *) echo "No pattern matched" ;; esac

Complex pattern matching examples

Advanced Usage

Multiple commands per case

#!/bin/bash operation="$1" file="$2" case $operation in backup) echo "Creating backup of $file" cp "$file" "$file.bak" echo "Backup created: $file.bak" ls -l "$file.bak" ;; restore) if [ -f "$file.bak" ]; then echo "Restoring $file from backup" cp "$file.bak" "$file" echo "File restored" else echo "No backup found for $file" exit 1 fi ;; clean) echo "Removing backup files" rm -f *.bak echo "Cleanup complete" ;; *) echo "Usage: $0 {backup|restore|clean} [filename]" ;; esac

Multiple commands and nested conditions

Case with functions

#!/bin/bash start_service() { echo "Starting service..." # Service start logic here return 0 } stop_service() { echo "Stopping service..." # Service stop logic here return 0 } show_status() { echo "Service status: Running" # Status check logic here } case $1 in start) start_service ;; stop) stop_service ;; restart) stop_service sleep 2 start_service ;; status) show_status ;; *) echo "Usage: $0 {start|stop|restart|status}" exit 1 ;; esac

Combine case statements with functions

Practical Examples

Menu system

#!/bin/bash show_menu() { echo "=== System Menu ===" echo "1. Show disk usage" echo "2. Show memory usage" echo "3. Show running processes" echo "4. Show network connections" echo "5. Exit" echo "==================" } while true; do show_menu read -p "Enter your choice (1-5): " choice case $choice in 1) echo "Disk Usage:" df -h ;; 2) echo "Memory Usage:" free -h ;; 3) echo "Running Processes:" ps aux | head -10 ;; 4) echo "Network Connections:" netstat -tuln | head -10 ;; 5) echo "Goodbye!" exit 0 ;; *) echo "Invalid choice. Please try again." ;; esac echo read -p "Press Enter to continue..." clear done

Interactive menu system

File processing script

#!/bin/bash process_file() { local file="$1" case $file in *.log) echo "Processing log file: $file" tail -n 20 "$file" ;; *.conf|*.config) echo "Configuration file: $file" grep -v '^#' "$file" | grep -v '^$' ;; *.sh) echo "Shell script: $file" if [ -x "$file" ]; then echo "Executable script" else echo "Non-executable script" fi ;; *.txt|*.md) echo "Text document: $file" wc -l "$file" ;; *) echo "Unknown file type: $file" file "$file" ;; esac } # Process all files in current directory for file in *; do if [ -f "$file" ]; then process_file "$file" echo "---" fi done

File processing based on extensions

System information script

#!/bin/bash get_os_info() { case $(uname -s) in Linux) echo "Operating System: Linux" if [ -f /etc/os-release ]; then . /etc/os-release echo "Distribution: $NAME $VERSION" fi ;; Darwin) echo "Operating System: macOS" echo "Version: $(sw_vers -productVersion)" ;; FreeBSD) echo "Operating System: FreeBSD" echo "Version: $(uname -r)" ;; *) echo "Operating System: $(uname -s)" echo "Version: $(uname -r)" ;; esac } get_arch_info() { case $(uname -m) in x86_64) echo "Architecture: 64-bit x86" ;; i386|i686) echo "Architecture: 32-bit x86" ;; arm64|aarch64) echo "Architecture: 64-bit ARM" ;; armv7l) echo "Architecture: 32-bit ARM" ;; *) echo "Architecture: $(uname -m)" ;; esac } get_os_info get_arch_info

System information detection

Best Practices

case Statement Best Practices
  • Always include a default case (*) for unmatched patterns
  • Use double semicolons (;;) to terminate each case
  • Group related patterns with | (pipe) separator
  • Quote variables to prevent word splitting
  • Use meaningful pattern names and comments
  • Consider case sensitivity in pattern matching
  • Test all possible input scenarios
Common Pitfalls
  • Missing ;; - Each case must end with double semicolon
  • Pattern order - More specific patterns should come first
  • Quoting - Unquoted variables can cause issues
  • Case sensitivity - Patterns are case-sensitive by default
  • Globbing - Patterns use shell globbing, not regex

See also