Flow Control and Branching With case in Linux: A Beginner’s Guide

Learn how to effectively use the case statement for flow control and branching in Linux scripting. This beginner-friendly guide covers syntax, practical examples, and common pitfalls to avoid, making it easy for new Linux programmers to implement decision-making logic in their scripts. Join me on this learning journey and enhance your bash scripting skills today!
code
linux
Author

Steven P. Sanderson II, MPH

Published

April 11, 2025

Keywords

Programming, Flow Control in Linux, Branching with Case, Bash Scripting, Linux Programming, Case Statement Syntax, Decision Making in Scripts, Bash Control Structures, Shell Scripting Basics, Menu Driven Programs, Pattern Matching in Bash, How to use case statement in Linux scripting, Examples of branching with case in Bash, Common pitfalls in Bash scripting for beginners, Creating a menu system using case in Linux, Understanding flow control mechanisms in shell scripts

This comprehensive guide explains how to use the case statement in Linux for clean, effective decision-making in your scripts. Perfect for beginners who want to understand branching logic and flow control with practical, working examples.

Author’s Note: I am learning this as I write this series. There might be some mistakes, so please point them out in the comments. We’ll learn together!

Introduction

When writing scripts in Linux, you’ll often need your program to make decisions based on different conditions. While the if statement is one way to handle this, the case statement provides a cleaner, more readable alternative when dealing with multiple choices. It’s especially useful for creating menu-driven programs or handling various command-line options.

The case statement is like a traffic director for your script - it examines a value and routes your program down different paths depending on what it finds. Let’s dive in!

Basic Syntax of the case Statement

Here’s the fundamental structure of a case statement:

case word in
    pattern1) commands ;;
    pattern2) commands ;;
    *) default_commands ;;
esac

Let’s break this down:

  • word is the variable or value you want to test
  • pattern1, pattern2, etc. are the patterns you’re matching against
  • commands are what you want to run when a match is found
  • *) is the catch-all pattern (like an “else” statement)
  • ;; marks the end of each case option
  • esac (that’s “case” spelled backward) closes the statement

Think of it like a multiple-choice question: “If the value is X, do this; if it’s Y, do that; otherwise, do something else.”

Simple Working Examples

Let’s look at some practical examples you can try right away.

Example 1: Simple Menu System

This is a classic use case for the case statement - creating a menu for users:

#!/bin/bash
echo "Please Select:
1. Display System Information
2. Display Disk Space
3. Display Home Space Utilization
0. Quit"
read -p "Enter selection [0-3] > "
case $REPLY in
    0) echo "Program terminated."
       exit ;;
    1) echo "Hostname: $HOSTNAME"
       uptime ;;
    2) df -h ;;
    3) echo "Home Space Utilization"
       du -sh $HOME ;;
    *) echo "Invalid entry" >&2
       exit 1 ;;
esac

How This Works:

  1. We display a menu with numbered options
  2. The read -p command asks for input with a prompt
  3. The case statement checks the value stored in $REPLY (the default variable for read)
  4. Based on what the user entered:
  • 0: The program displays “Program terminated” and exits
  • 1: Shows the hostname and uptime information
  • 2: Displays disk space usage with df -h (human-readable format)
  • 3: Shows home directory space usage
  • Any other input: Shows an error message and exits with error code 1

This is much cleaner than writing multiple if/elif/else statements!

Example 2: Yes/No Response Handler

Here’s a simple script that processes yes/no responses:

#!/bin/bash
read -p "Do you want to continue? (y/n) > " answer
case $answer in
    [Yy]|[Yy][Ee][Ss]) 
        echo "Continuing..."
        ;;
    [Nn]|[Nn][Oo])
        echo "Stopping..."
        exit 0
        ;;
    *)
        echo "Invalid response - please answer y or n"
        exit 1
        ;;
esac

How This Works:

  1. The script asks if the user wants to continue
  2. The case statement:
  • Matches y, Y, yes, YES, etc. using pattern [Yy]|[Yy][Ee][Ss]
  • Matches n, N, no, NO, etc. using pattern [Nn]|[Nn][Oo]
  • For any other input, shows an error message

This example shows how to use pattern matching to accept multiple forms of the same answer.

Example 3: File Type Handler

This script demonstrates how to perform actions based on file extensions:

#!/bin/bash
file="example.txt"
case $file in
    *.txt) echo "Text file" ;;
    *.jpg|*.png) echo "Image file" ;;
    *.sh) echo "Shell script" ;;
    *) echo "Unknown file type" ;;
esac

How This Works:

  1. We define a variable file with the value “example.txt”
  2. The case statement checks the file name against different patterns:
  • *.txt matches files ending with .txt
  • *.jpg|*.png matches files ending with either .jpg or .png
  • *.sh matches shell scripts
  • * matches anything else

Try modifying the file variable to see different results!

Pattern Matching Features

The case statement supports several pattern matching techniques:

  1. Single character matches: 'a)' matches the character ‘a’

  2. Character classes: [[:alpha:]]) matches any alphabetic character

    char="a"
    case $char in
        [[:lower:]]) echo "Lowercase letter" ;;
        [[:upper:]]) echo "Uppercase letter" ;;
        [[:digit:]]) echo "Digit" ;;
        *) echo "Other character" ;;
    esac
  3. Multiple patterns using |: 'a|A)' matches either ‘a’ or ‘A’

  4. Wildcard matching: '*.txt)' matches any string ending with .txt

  5. Day of Week Example: Group similar cases together

    #!/bin/bash
    # Get current day of week (1-7, 1 is Monday)
    day=$(date +%u)
    case $day in
        1)
            echo "It's Monday - Start of the work week!"
            ;;
        2|3|4)
            echo "It's a regular work day"
            ;;
        5)
            echo "It's Friday - Almost weekend!"
            ;;
        6|7)
            echo "It's the weekend!"
            ;;
        *)
            echo "Invalid day number"
            ;;
    esac

This example shows how to group cases (like treating Tuesday, Wednesday, and Thursday the same).

Advanced Feature: Multiple Actions Per Match

In Bash 4.0 and newer, you can use ;;& instead of ;; to continue checking patterns even after a match:

case $char in
    [[:lower:]]) echo "Is lowercase" ;;&
    [[:alpha:]]) echo "Is alphabetic" ;;&
esac

If $char contains a lowercase letter, both messages will be displayed because the script continues checking patterns after the first match.


Common Mistakes to Avoid

When using case statements, watch out for these beginner pitfalls:

1. Forgetting the Catch-all Pattern

Always include a catch-all pattern (*) as the last case. Without it, unexpected input might not be handled properly:

# Bad example - no catch-all
case $choice in
    1) echo "Option 1" ;;
    2) echo "Option 2" ;;
esac

# Good example - with catch-all
case $choice in
    1) echo "Option 1" ;;
    2) echo "Option 2" ;;
    *) echo "Invalid option" ;;
esac

2. Not Quoting Variables

When using variables in scripts, always quote them to handle spaces and special characters properly:

# Bad example - unquoted variable
file=my file.txt  # This will cause an error!
case $file in   # Should be "$file"
    *.txt) echo "Text file" ;;
esac

# Good example - quoted variable
file="my file.txt"
case "$file" in
    *.txt) echo "Text file" ;;
    *) echo "Other file" ;;
esac

3. Forgetting ;;

Each case pattern must end with ;; - forgetting this will cause syntax errors:

# Bad example - missing ;;
case $choice in
    1) echo "Option 1"    # Missing ;;
    2) echo "Option 2" ;;
esac

# Good example
case $choice in
    1) echo "Option 1" ;;
    2) echo "Option 2" ;;
esac

4. Mixing Up case Syntax With if Syntax

Remember that case has its own unique syntax different from if statements:

# Bad example - mixing syntaxes
case $choice in
    if $choice -eq 1; then  # Wrong! Don't use if inside case
        echo "Option 1"
    fi ;;
esac

# Good example
case $choice in
    1) echo "Option 1" ;;
esac

Best Practices for Using case Statements

Follow these guidelines for clean, effective case statements:

  1. Use for multiple choices: When you have 3+ options, case is usually cleaner than if/elif/else

  2. Add comments for complex patterns: Explain what your patterns are matching

  3. Include a catch-all pattern: Always add *) as the last case

  4. Group related patterns: Use the | operator to group similar cases

  5. Quote your variables: Always use quotes around variables: "$variable"

  6. Test your scripts: Try different inputs to ensure your script handles all cases


Your Turn!

Let’s practice! Try writing a simple script that takes a command-line argument and tells you whether it’s a vowel, consonant, number, or something else.

Here’s a starter template:

#!/bin/bash
# Check if an argument was provided
if [ $# -eq 0 ]; then
    echo "Please provide a single character as an argument"
    exit 1
fi

# Get the first character of the first argument
char="${1:0:1}"

# YOUR case STATEMENT HERE
case ... in
    # Your patterns here
esac
Click to See Solution!
#!/bin/bash
# Check if an argument was provided
if [ $# -eq 0 ]; then
    echo "Please provide a single character as an argument"
    exit 1
fi

# Get the first character of the first argument
char="${1:0:1}"

# Check the character type
case "$char" in
    [aeiouAEIOU]) 
        echo "'$char' is a vowel"
        ;;
    [bcdfghjklmnpqrstvwxyzBCDFGHJKLMNPQRSTVWXYZ])
        echo "'$char' is a consonant"
        ;;
    [0-9])
        echo "'$char' is a number"
        ;;
    *)
        echo "'$char' is a special character"
        ;;
esac
Save this to a file (e.g., charcheck.sh), make it executable with chmod +x charcheck.sh, and run it with a character argument: ./charcheck.sh a

Key Takeaways

  • The case statement provides a clean way to handle multiple choice decisions in shell scripts
  • It’s more readable than multiple if statements for handling several conditions
  • Basic syntax: case variable in pattern) commands ;; esac
  • Always include a catch-all pattern (*) as the last case
  • Use pattern matching features like wildcards (*), character classes ([:alpha:]), and pattern grouping (|)
  • Quote your variables to avoid issues with spaces and special characters
  • Test your scripts with various inputs to ensure they work correctly

Conclusion

The case statement is an essential tool in your Linux scripting arsenal. By using it effectively, you can create cleaner, more readable scripts that handle multiple conditions elegantly. Whether you’re building a menu system, processing command-line options, or categorizing data, the case statement offers a structured approach to decision-making in your scripts.

Remember that practice is key - try modifying the examples we’ve covered and create your own scripts to solidify your understanding. As you become more comfortable with case statements, you’ll find they make your scripts more maintainable and easier to debug.

Frequently Asked Questions

1. When should I use a case statement instead of if/else?

Use a case statement when you need to check a single variable against multiple possible values. If you find yourself writing many elif statements checking the same variable, consider switching to case.

2. Can I use case with numbers?

Absolutely! You can match specific numbers or ranges. For example: case $num in 1) ... ;; [2-5]) ... ;; esac

3. How do I match multiple patterns in one case?

Use the pipe symbol (|) to match multiple patterns: case $var in a|A|apple) ... ;; esac

4. Can I use wildcards in case patterns?

Yes, you can use wildcards like * (matches anything) and ? (matches any single character).

5. How do I make case statements case-insensitive?

You can either use pattern grouping like [Yy][Ee][Ss] to match “yes”, “YES”, “Yes”, etc., or use the shopt -s nocasematch command before your case statement (but remember to reset it with shopt -u nocasematch after).


References

  1. Shell Tips - “Top 10 Bash Pitfalls You Don’t Want to Make”
    A comprehensive guide to common mistakes in bash scripting and how to avoid them.

  2. Stack Overflow - “Bash does not allow if statement inside case statement”
    Discussion of syntax limitations when combining different control structures in bash scripts.


Further Reading

The following resources were also mentioned in the original document:


Note to readers: If you found this guide helpful, please consider bookmarking these resources for future reference. The online bash community is also an excellent place to ask questions and share your own experiences with flow control in Linux scripting.

Have you discovered any other helpful resources for learning bash scripting? Feel free to share them in the comments below!


Happy Coding! 🚀

case esac in Linux

You can connect with me at any one of the below:

Telegram Channel here: https://t.me/steveondata

LinkedIn Network here: https://www.linkedin.com/in/spsanderson/

Mastadon Social here: https://mstdn.social/@stevensanderson

RStats Network here: https://rstats.me/@spsanderson

GitHub Network here: https://github.com/spsanderson

Bluesky Network here: https://bsky.app/profile/spsanderson.com

My Book: Extending Excel with Python and R here: https://packt.link/oTyZJ

You.com Referral Link: https://you.com/join/EHSLDTL6