Language
日本語
English

Caution

JavaScript is disabled in your browser.
This site uses JavaScript for features such as search.
For the best experience, please enable JavaScript before browsing this site.

Linux & Mac & Bash Command Dictionary

  1. Home
  2. Linux & Mac & Bash Command Dictionary
  3. case

case

The case statement matches a variable or command output against patterns and branches execution accordingly. It provides a clean way to handle multiple values, making it ideal for processing command-line arguments and building menu-driven scripts.

Syntax

case variable in
    pattern1)
        action1
        ;;
    pattern2 | pattern3)
        action2
        ;;
    *)
        default action
        ;;
esac

Pattern List

PatternDescription
word)Exact match. Executes when the value equals word.
pat1 | pat2)OR condition. Executes when the value matches either pattern.
*.txt)Wildcard pattern. Matches any string ending in .txt.
[aeiou])Character class. Matches any one of the characters a, e, i, o, or u.
?)Matches exactly one character. ??) matches two characters, ???) matches three. Useful for fixed-length patterns.
[0-9])Range character class. Matches any one digit from 0 to 9.
[!a-z])Negated character class. Matches any single character that is NOT a lowercase letter.
*)Default pattern that matches everything. Place it last.
;;Terminates a pattern block (does not fall through to the next pattern).
;&Falls through and executes the next pattern block regardless (Bash 4+).
;;&Evaluates the next pattern and executes it if it matches (Bash 4+).

Sample Code

Branches execution based on a command-line argument. Use | to combine multiple values into a single OR condition.

sample_service.sh
#!/bin/bash
action=$1

case "$action" in
    start)
        echo "Starting the service"
        ;;
    stop)
        echo "Stopping the service"
        ;;
    restart | reload)
        echo "Restarting the service"
        ;;
    status)
        echo "Checking service status"
        ;;
    *)
        echo "Usage: $0 {start|stop|restart|reload|status}"
        exit 1
        ;;
esac

Run the following command:

bash service.sh restart
Restarting the service

Uses wildcard patterns to determine a file type by its extension.

sample_filetype.sh
filename="report.pdf"
case "$filename" in
    *.php | *.py | *.rb)
        echo "Script file"
        ;;
    *.txt | *.md | *.csv)
        echo "Text file"
        ;;
    *.jpg | *.png | *.gif)
        echo "Image file"
        ;;
    *.pdf)
        echo "PDF file"
        ;;
    *)
        echo "Unknown file type"
        ;;
esac

Run the following command:

bash filetype.sh
PDF file

Uses the character class [0-9] to check a numeric range.

sample_grade_case.sh
score=85
case $score in
    9[0-9] | 100)
        echo "A (Excellent)"
        ;;
    8[0-9])
        echo "B (Good)"
        ;;
    7[0-9])
        echo "C (Pass)"
        ;;
    *)
        echo "D (Fail)"
        ;;
esac

Run the following command:

bash grade_case.sh
B (Good)

? is a wildcard that matches exactly one character. It is useful when matching against a fixed-length input. For example, ???) matches three characters and ?????) matches five characters. This makes it convenient for validating ZIP codes, fixed-length IDs, and similar formats.

sample_zip_check.sh
zip=$1

case "$zip" in
    ???-????)
        echo "Japanese ZIP code format (3 digits - 4 digits)"
        ;;
    ?????)
        echo "5-digit number (US ZIP or legacy format)"
        ;;
    ?)
        echo "Only one character was entered"
        ;;
    "")
        echo "Empty string"
        ;;
    *)
        echo "Unrecognized format"
        ;;
esac

Run the following command:

bash zip_check.sh 100-0001
Japanese ZIP code format (3 digits - 4 digits)
bash zip_check.sh 12345
5-digit number (US ZIP or legacy format)
bash zip_check.sh A
Only one character was entered

? means "exactly one character", not "one or more characters". ??) matches strings of length 2 — it does not match a 1-character or 3-character string. To match an arbitrary number of characters, use * instead.

Common Mistakes

Common Mistake 1: Forgetting ;; causes fall-through to the next pattern

Each case block must end with ;;. Without it, execution falls through to the next block and produces unexpected results.

service_ng.sh
#!/bin/bash
action=$1

case "$action" in
    start)
        echo "Starting service"
        # ;; is missing here
    stop)
        echo "Stopping service"
        ;;
esac

The following example demonstrates this:

bash service_ng.sh start
Starting service
Stopping service

Terminating each block with ;; ensures only the intended block executes.

service_ok.sh
#!/bin/bash
action=$1

case "$action" in
    start)
        echo "Starting service"
        ;;
    stop)
        echo "Stopping service"
        ;;
esac

Run the following command:

bash service_ok.sh start
Starting service

Common Mistake 2: Passing an unquoted variable with spaces breaks matching

If the variable contains spaces and is not quoted, the shell splits it into multiple words before matching, causing the case statement to fail unexpectedly.

case_unquoted_ng.sh
#!/bin/bash
msg="hello world"

case $msg in
    "hello world")
        echo "matched"
        ;;
    *)
        echo "no match"
        ;;
esac

Run the following command:

bash case_unquoted_ng.sh
no match

Quoting the variable preserves spaces and allows the pattern to match correctly.

case_quoted_ok.sh
#!/bin/bash
msg="hello world"

case "$msg" in
    "hello world")
        echo "matched"
        ;;
    *)
        echo "no match"
        ;;
esac

Run the following command:

bash case_quoted_ok.sh
matched

Notes

Case patterns use shell glob patterns (wildcards), not regular expressions. If you need regex matching, use the =~ operator with if / [[ ]].

Separating patterns with | lets you group OR conditions into a single block. Compared to if-elif chains, case is more concise and easier to read.

The default pattern *) is optional, but it is recommended to always include it to handle unexpected input gracefully.

If you find any errors or copyright issues, please .