How to use a case statement in Bash

A Bash case statement matches one value against several named patterns and runs the branch for the first match. It is easier to scan than a long if and elif chain when one argument selects actions such as start, stop, status, or reload.

The block starts with case "$value" in, each pattern line ends with ), each branch finishes with ;;, and the whole block closes with esac. Multiple accepted words can share one branch by separating patterns with |, while * is commonly used as the fallback branch.

A service-style action script can use the first argument as the action and fall back to status when no argument is supplied. Branch tests should cover the default action, a single-pattern branch, a shared-pattern branch, and the failure path that returns a nonzero status.

Steps to use a case statement in Bash:

  1. Create a script that dispatches on the first argument.
    service-action.sh
    #!/usr/bin/env bash
    set -euo pipefail
     
    action=${1:-status}
     
    case "$action" in
        start)
            printf "starting service\n"
            ;;
        stop)
            printf "stopping service\n"
            ;;
        status)
            printf "service is running\n"
            ;;
        restart|reload)
            printf "refreshing service\n"
            ;;
        *)
            printf "unknown action: %s\n" "$action" >&2
            exit 2
            ;;
    esac

    Quote the value being matched so an empty or space-containing argument is still treated as one value.

  2. Check the script syntax.
    $ bash -n service-action.sh
  3. Run the default status branch.
    $ bash service-action.sh
    service is running
  4. Run a single-pattern branch.
    $ bash service-action.sh start
    starting service
  5. Run a branch shared by two patterns.
    $ bash service-action.sh reload
    refreshing service
  6. Verify that an unknown action prints an error and exits with status 2.
    $ bash service-action.sh remove
    unknown action: remove
    $ printf 'exit=%s\n' "$?"
    exit=2

    Capture the exit status immediately after the command being tested. Running another command first replaces $? with that command's status.

  7. Remove the sample script when the branch tests are finished.
    $ rm -f service-action.sh