bash parse arguments with getopts and $@

#!/usr/bin/env bash
# Positional args: $1, $2, $3...
echo "First arg: $1"
echo "All args:  $@"
echo "Arg count: $#"

You need to handle flags (-v, -o filename) or positional arguments in a bash script.

Parse flags with getopts

#!/usr/bin/env bash
while getopts "vo:h" opt; do
  case $opt in
    v) verbose=1 ;;
    o) output="$OPTARG" ;;
    h) echo "Usage: $0 [-v] [-o output] args"; exit 0 ;;
    *) echo "Unknown option: $opt"; exit 1 ;;
  esac
done
shift $((OPTIND - 1))   # remove parsed flags, $@ now has remaining args
echo "Remaining args: $@"

Parse long options with --

getopts does not support long options (--flag). Use a case statement with shift instead.

#!/usr/bin/env bash
while [[ $# -gt 0 ]]; do
  case $1 in
    --verbose|-v) verbose=1; shift ;;
    --output|-o)  output="$2"; shift 2 ;;
    --help|-h)    echo "Usage: ..."; exit 0 ;;
    --)           shift; break ;;
    *)            positional+=("$1"); shift ;;
  esac
done

Default values for arguments

name="${1:-world}"     # default to "world" if $1 is empty
echo "Hello, $name!"