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

Hemang picture Hemang · Aug 19, 2012 · Viewed 62.9k times · Source

I am trying to parse a -temp option with Bash getopts. I'm calling my script like this:

./myscript -temp /foo/bar/someFile

Here is the code I'm using to parse the options.

while getopts "temp:shots:o:" option; do
    case $option in
        temp) TMPDIR="$OPTARG" ;;
        shots) NUMSHOTS="$OPTARG" ;;
        o) OUTFILE="$OPTARG" ;;
        *) usage ;;
    esac
done
shift $(($OPTIND - 1))

[ $# -lt 1 ] && usage

Answer

mcoolive picture mcoolive · May 4, 2015

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" ;;
    "--rest") set -- "$@" "-r" ;;
    "--ws")   set -- "$@" "-w" ;;
    *)        set -- "$@" "$arg"
  esac
done

# Default behavior
rest=false; ws=false

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