How can I use long options with the Bash getopts builtin?

As other people explained, getopts doesn’t parse long options. You can use getopt, but it’s not portable (and it is broken on some platform…)

As a workaround, you can implement a shell loop. Here an example that transforms long options to short ones before using the standard getopts command (it’s simpler in my opinion):

# Transform long options to short ones
for arg in "$@"; do
  shift
  case "$arg" in
    '--help')   set -- "$@" '-h'   ;;
    '--number') set -- "$@" '-n'   ;;
    '--rest')   set -- "$@" '-r'   ;;
    '--ws')     set -- "$@" '-w'   ;;
    *)          set -- "$@" "$arg" ;;
  esac
done

# Default behavior
number=0; rest=false; ws=false

# Parse short options
OPTIND=1
while getopts "hn:rw" opt
do
  case "$opt" in
    'h') print_usage; exit 0 ;;
    'n') number=$OPTARG ;;
    'r') rest=true ;;
    'w') ws=true ;;
    '?') print_usage >&2; exit 1 ;;
  esac
done
shift $(expr $OPTIND - 1) # remove options from positional parameters

Leave a Comment