The Zsh getopts builtin lets a script accept short options such as -n and -r eu-west-1 before the remaining arguments. Named flags make repeated runs easier to inspect in shell history, scheduled jobs, and deployment notes than a script that depends on positional order alone.

getopts reads one option per loop pass, writes the current option letter into the loop variable, stores option values in OPTARG, and advances OPTIND so parsed flags can be removed from the argument list. A leading colon in the option string lets the script print its own messages for missing values and unknown options.

The sample parser sets dry-run mode, accepts an override region, and leaves the environment name as the remaining argument after shift. The checks confirm that the file parses, a normal run prints the parsed values, and bad option input fails before the script continues.

Steps to use getopts in Zsh:

  1. Create a Zsh script with one flag option and one option that requires a value.
    deploy-options.zsh
    #!/usr/bin/env zsh
    emulate -L zsh
    setopt err_exit no_unset
     
    region="us-east-1"
    dry_run=0
    environment=""
     
    while getopts ":nr:" opt; do
        case "$opt" in
            n)
                dry_run=1
                ;;
            r)
                region=$OPTARG
                ;;
            :)
                print -u2 -- "missing value for -$OPTARG"
                exit 1
                ;;
            \?)
                print -u2 -- "unknown option: -$OPTARG"
                exit 1
                ;;
        esac
    done
     
    shift $((OPTIND - 1))
    environment=${1:-}
     
    if (( ${#environment} == 0 )); then
        print -u2 -- "missing environment"
        exit 1
    fi
     
    print -r -- "environment=$environment"
    print -r -- "region=$region"
    print -r -- "dry_run=$dry_run"

    The option string :nr: means -n is a flag, -r requires a value, and missing values are handled by the :) branch.

  2. Check the script syntax before testing option parsing.
    $ zsh -n deploy-options.zsh

    No output from zsh -n means Zsh parsed the script without finding a syntax error.

  3. Run the script with both options and the remaining environment argument.
    $ zsh deploy-options.zsh -n -r eu-west-1 staging
    environment=staging
    region=eu-west-1
    dry_run=1

    The command keeps options before the remaining staging argument, so getopts can finish before the script reads the environment name.

  4. Use OPTIND to remove parsed options before reading the remaining argument.
    shift $((OPTIND - 1))
    environment=${1:-}

    After the shift, $1 refers to the first non-option argument rather than -n, -r, or the region value.

  5. Confirm that a missing option value exits before any deployment state is printed.
    $ zsh deploy-options.zsh -r
    missing value for -r

    Keep the leading colon in :nr: when the script needs its own missing-value message. Without it, Zsh prints the default getopts diagnostic.

  6. Confirm that an unknown option uses the custom invalid-option branch.
    $ zsh deploy-options.zsh -x staging
    unknown option: -x

    With the leading colon in :nr:, the invalid option letter is available in OPTARG for the error message.

  7. Remove the sample script after testing.
    $ rm deploy-options.zsh