A Zsh case statement lets a script choose one branch from a fixed set of words or shell patterns. It fits command dispatch, environment selection, and menu-style script arguments where a long chain of string comparisons would be harder to scan.
Each branch starts with a pattern ending in ) and ends with ;;. Multiple accepted words can share one branch with |, and a final * branch catches values that do not match any earlier pattern.
The example maps a target name to a URL, validates the file with zsh -n, and runs matched and unmatched inputs. Known targets print the selected URL, while empty or unknown targets print guard messages instead of a URL.
Related: How to use conditionals in Zsh
Related: How to use getopts in Zsh
Related: Use a case statement in Bash
#!/usr/bin/env zsh
emulate -L zsh
setopt err_exit no_unset
target=${1:-}
case "$target" in
dev|development)
url="https://dev.example.com"
;;
staging)
url="https://staging.example.com"
;;
production|prod)
url="https://www.example.com"
;;
"")
print -u2 -- "missing target"
exit 1
;;
*)
print -u2 -- "unknown target: $target"
exit 1
;;
esac
print -r -- "target=$target"
print -r -- "url=$url"
The dev|development and production|prod branches accept two words each. The quoted empty-string branch handles a missing argument before the fallback * branch handles unsupported targets.
$ zsh -n deploy-target.zsh
No output from zsh -n means Zsh parsed the case block, branch endings, and esac marker without finding a syntax error.
$ zsh deploy-target.zsh staging target=staging url=https://staging.example.com
$ zsh deploy-target.zsh production target=production url=https://www.example.com
$ zsh deploy-target.zsh sandbox unknown target: sandbox
Keep the fallback * branch last. Earlier patterns are tested first, so a leading * branch would catch every value before the specific branches can run.
$ zsh deploy-target.zsh missing target
$ rm -f deploy-target.zsh