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.

  1. Home
  2. Shell Script Dictionary
  3. case

case

Since: 基本構文(;; / *) POSIX(sh互換)
;& ;;& (fallthrough) Bash(bash拡張)

The case statement in shell scripts matches the value of a variable or string against patterns and branches execution accordingly. The same branching can be done with if-elif-else, but when there are many branches, case is far more readable. A case block is closed with esac (the word "case" reversed). Each pattern ends with ), and ;; is placed at the end of the processing block to explicitly signal that execution does not fall through to the next pattern.

Basic Syntax

A case statement lists patterns after the in keyword and is closed with esac.

ElementMeaningDescription
case value inBegin matchingMatches the value against patterns. Variables, command substitutions, and string literals can be used.
pattern)Pattern definitionSpecifies the pattern to match. Glob notation is available.
;;End block, do not fall throughFinishes processing this pattern and exits the entire case statement.
;;&End block, continue evaluating (bash 4.0+)After processing this pattern, continues evaluating subsequent patterns. Executes any that match.
;&End block, unconditionally execute next (bash 4.0+)After processing this pattern, unconditionally executes the next pattern's processing without evaluation (equivalent to C's fallthrough).
*)Default (wildcard)Executed when no other pattern matches.
esacTerminatorCloses the case block.
# Basic case statement structure
case value in
    pattern1)
        # Executed when pattern1 matches
        processing_A
        ;;
    pattern2)
        # Executed when pattern2 matches
        processing_B
        ;;
    *)
        # Executed when no pattern matches
        default_processing
        ;;
esac

Writing Patterns

Patterns support glob notation and multiple alternatives with |. Note that regular expressions cannot be used.

PatternMeaningDescription
stringExact matchMatches when the value exactly equals the specified string.
*Any string (0 or more characters)Matches anything. Used for the default case.
?Any single characterMatches any single character. Used to match by character count.
[abc]Character classMatches any one of the characters inside the brackets.
[a-z]Character rangeMatches any single character within the specified range.
patternA|patternBOR (multiple patterns)Executes when either pattern matches. Used to apply the same processing to multiple values.

Difference Between ;; and ;;&

The type of terminator (the symbol at the end of a pattern block) determines behavior after a match. ;;& and ;& are only available in bash 4.0 and later.

TerminatorBehaviorDescription
;;Immediate exitAfter executing this pattern's processing, exits the entire case statement. The most common form.
;;&Continue evaluating next patternsAfter executing this pattern's processing, continues evaluating the remaining patterns from the top. Executes any that match.
;&Unconditionally execute nextAfter executing this pattern's processing, unconditionally executes the next pattern's processing without evaluation (same behavior as C's fallthrough).

Sample Code

eva_case_basic.sh
#!/bin/bash
# -----------------------------------------------
#  Branch on Evangelion pilots using a case statement
#  (basic exact match example using ;;)
# -----------------------------------------------

# Set the pilot name to evaluate
pilot="Soryu Asuka"

echo "=== Pilot identification ==="
echo "Target: ${pilot}"
echo ""

case "$pilot" in
    "Ikari Shinji")
        # Unit-01 pilot
        echo "Unit: Evangelion Unit-01 (backup pilot for Unit-00)"
        echo "Unit number: Unit-01"
        ;;
    "Ayanami Rei")
        # Unit-00 pilot
        echo "Unit: Evangelion Unit-00"
        echo "Unit number: Unit-00"
        ;;
    "Soryu Asuka")
        # Unit-02 pilot
        echo "Unit: Evangelion Unit-02"
        echo "Unit number: Unit-02"
        ;;
    "Nagisa Kaworu")
        # 17th Angel / 5th candidate
        echo "Unit: Evangelion Unit-03 (provisional)"
        echo "Unit number: Unit-02 (including Unit-13)"
        ;;
    "Makinami Mari")
        # Provisional Unit-05 / Unit-02' pilot
        echo "Unit: Evangelion Provisional Unit-05 / Unit-02'"
        echo "Unit number: Unit-05 / Unit-02'"
        ;;
    *)
        # Pilot not in the registry
        echo "${pilot} is not registered in the pilot roster."
        ;;
esac
chmod +x eva_case_basic.sh
./eva_case_basic.sh
=== Pilot identification ===
Target: Soryu Asuka

Unit: Evangelion Unit-02
Unit number: Unit-02
eva_case_pattern.sh
#!/bin/bash
# -----------------------------------------------
#  Example using wildcards, ?, and | for pattern matching
#  Classifies Angel battle records (codenames) by pilot
# -----------------------------------------------

# Receive a status code from a command-line argument
# Default to "A-001" if no argument is given
code="${1:-A-001}"

echo "=== Angel battle code classification: ${code} ==="
echo ""

case "$code" in
    A-???)
        # Matches "A-" followed by any 3 characters (Angel battles 1-999)
        echo "Classification: Angel engagement record (Ikari Shinji / Ayanami Rei / Soryu Asuka)"
        ;;
    E-001|E-002|E-003)
        # Use | to specify multiple values with OR
        # E-001: Ikari Shinji, E-002: Ayanami Rei, E-003: Soryu Asuka sortie records
        echo "Classification: Initial pilot sortie record (Shinji / Rei / Asuka)"
        ;;
    E-004|E-005)
        # E-004: Nagisa Kaworu, E-005: Makinami Mari sortie records
        echo "Classification: Additional pilot sortie record (Kaworu / Mari)"
        ;;
    M-[0-9][0-9][0-9])
        # Matches "M-" followed by exactly 3 digits (operation codes)
        echo "Classification: NERV operation record"
        ;;
    [a-z]*)
        # Codes starting with a lowercase letter are treated as unofficial logs
        echo "Classification: Unofficial log (codes starting with lowercase are unauthenticated)"
        ;;
    *)
        # Does not match any of the above
        echo "Classification: Unknown code (check with MAGI system)"
        ;;
esac
chmod +x eva_case_pattern.sh

# Matches A-???
./eva_case_pattern.sh A-003
=== Angel battle code classification: A-003 ===

Classification: Angel engagement record (Ikari Shinji / Ayanami Rei / Soryu Asuka)

# Matches the | multi-pattern
./eva_case_pattern.sh E-002
=== Angel battle code classification: E-002 ===

Classification: Initial pilot sortie record (Shinji / Rei / Asuka)

# Matches [0-9][0-9][0-9]
./eva_case_pattern.sh M-007
=== Angel battle code classification: M-007 ===

Classification: NERV operation record

# Matches default (*)
./eva_case_pattern.sh X-99
=== Angel battle code classification: X-99 ===

Classification: Unknown code (check with MAGI system)
eva_case_fallthrough.sh
#!/bin/bash
# -----------------------------------------------
#  Comparing ;; and ;;&
#  (requires bash 4.0 or later)
#  Classifying pilots by suitability rank with tags
# -----------------------------------------------

# Set the pilot name to evaluate
pilot="Ikari Shinji"

echo "=== Using ;; (exit immediately on match) ==="
echo "Target: ${pilot}"
echo ""

# With ;; only the first matching pattern executes, then the case exits
case "$pilot" in
    "Ikari Shinji"|"Ayanami Rei"|"Soryu Asuka")
        echo "[tag] Initial pilot"
        ;;
    "Ikari Shinji"|"Nagisa Kaworu")
        # With ;; the case exits after the first match
        # This block can never be reached
        echo "[tag] Soul lineage"
        ;;
    *)
        echo "[tag] Other"
        ;;
esac

echo ""
echo "=== Using ;;& (continue evaluating after match) ==="
echo "Target: ${pilot}"
echo ""

# With ;;& evaluation continues over remaining patterns after a match
# Used to assign multiple tags when a value matches multiple patterns
case "$pilot" in
    "Ikari Shinji"|"Ayanami Rei"|"Soryu Asuka")
        echo "[tag] Initial pilot"
        ;;&    # <- continue evaluating next patterns even after a match
    "Ikari Shinji"|"Nagisa Kaworu")
        echo "[tag] Soul lineage"
        ;;&    # <- continue evaluating
    "Makinami Mari"|"Ikari Shinji")
        echo "[tag] Main pilot (theatrical)"
        ;;&
    *)
        # * always matches, so a common tag is added for everyone
        echo "[tag] NERV registered"
        ;;
esac
chmod +x eva_case_fallthrough.sh
./eva_case_fallthrough.sh
=== Using ;; (exit immediately on match) ===
Target: Ikari Shinji

[tag] Initial pilot

=== Using ;;& (continue evaluating after match) ===
Target: Ikari Shinji

[tag] Initial pilot
[tag] Soul lineage
[tag] Main pilot (theatrical)
[tag] NERV registered

When to Use case vs if

Aspectcase statementif statement
Best suited forMatching a single variable against multiple values or patterns.Conditions combining multiple variables or numeric comparisons.
Pattern matchingGlob notation (*, ?, [abc]) is available.Globs and regular expressions (=~) are available inside [[ ]].
Numeric comparisonNot available (string matching only).Numeric comparisons are available with -eq, -lt, -gt, etc.
ReadabilityCleaner when there are many branches.Better suited when there are few branches but complex conditions.
POSIX compliancePOSIX-compliant with ;; only. ;;& and ;& require bash 4.0+.POSIX-compliant when using [ ].

Notes

The case statement in shell scripts matches a single variable or command output against multiple patterns and branches execution. The block is closed with esac, and each pattern ends with ). Glob notation (*, ?, [abc]) is available in patterns, and multiple patterns can be combined with | as an OR condition. The terminator at the end of each block is normally ;; (immediate exit), but bash 4.0+ also supports ;;& (continue evaluating after match) and ;& (unconditionally execute next). When conditions combine multiple variables or require numeric comparisons, use if statements. See also [ ] and [[ ]] for details on conditional expressions.

If you find any errors or copyright issues, please .