case matches a value against patterns and runs the first branch that fits. It is bash's switch statement, and it earns its keep the moment a script grows subcommands: deploy.sh start, stop, status — an if-ladder for that reads like alphabet soup; case reads like a table of contents.

The shape #

Dispatch on the first argument
case "$1" in
  start)  echo "starting aospix" ;;
  stop)   echo "stopping aospix" ;;
  status) systemctl status aospix ;;
  restart) echo "restarting";;
  *) echo "usage: $0 {start|stop|status|restart}" >&2; exit 1 ;;
esac

The syntax is case value in pattern) commands ;; branches, closed by esac (case backwards, like if/fi). Patterns use glob syntax — * matches anything, so the final *) is the default branch, and its job is usually the usage message with a non-zero exit code.

Patterns are globs, and they compose #

PatternMatches
start) Exactly "start"
`-h--help)`Either spelling
v*)Anything starting with v
*.conf)Files ending in .conf
?????)Exactly five characters
*)Everything — the default

Alternation inside a branch is a pipe of patterns, not a regex — same glob family as filename expansion, which is why *.log) needs no quoting worries.

The classic uses #

Parsing a script's own subcommands, as above, is half of all case usage. The other half is classifying values from data:

Route by file extension
case "$file" in
  *.tar.gz|*.tgz) tar -xzf "$file" ;;
  *.zip)          unzip "$file" ;;
  *.png|*.jpg)    echo "image: $file" ;;
  *)              echo "unknown type: $file" ;;
esac

Combined with a for loop, that pattern processes a whole directory by type — the skeleton of most file-organising scripts.

The details that matter #

  • ;; ends each branch (and bash's ;& falls through deliberately, ;;& continues testing — rarely needed, good to recognise).
  • The value should be quoted ("$1"); patterns should not be.
  • case does not expand the matched value, so globby input is safe.

Arguments feeding the case come from $1 and getopts; the branches usually end in tidy exit codes. The scripting series continues.