Skip to main content
2 of 4
added 1021 characters in body
Vera
  • 1.4k
  • 2
  • 15
  • 33

Handling long-options with getopts

I am parsing options with getopts but would like to handle long-options as well.

print-args () { title="$1" ; shift printf "\n%s\n" "${title}: \$@:" for arg in "$@"; do (( i = i + 1 )) printf "%s |%s|\n" "${i}." "$arg" done } getopts_test () { aggr=() for arg in "$@"; do case $arg in ("--colour"|"--color") aggr+=( "-c" ) ;; ("--colour="*|"--color="*) aggr+=( "-c" "${arg#*=}" ) ;; (*) aggr+=( "$arg" ) ;; esac done print-args "print" "$@" eval set -- "${aggr[@]}" print-args "eval" "$@" set -- "${aggr[@]}" print-args "set" "$@" local OPTIND OPTARG local shortopts="C:" while getopts "$shortopts" arg; do case $arg in ("c") context="$OPTARG" ;; (*) break ;; esac done shift $(( OPTIND - 1 )) } 

But I wonder whether the use of set -- "${aggr[@]}" is correct.

Or is the following (using eval) more appropriate?

eval set -- "${aggr[@]}" 

I have performed a test shown below. With eval, the string "Gunga Din" is split up, whereas with set -- "${aggr[@]}", it is being parsed correctly as a single string.

getopts_test -f -g 130 --colour="170 20" "Gunga Din" print: $@: 1. |-f| 2. |-g| 3. |130| 4. |--colour=170 20| 5. |Gunga Din| eval: $@: 1. |-f| 2. |-g| 3. |130| 4. |-c| 5. |170| 6. |20| 7. |Gunga| 8. |Din| set: $@: 1. |-f| 2. |-g| 3. |130| 4. |-c| 5. |170 20| 6. |Gunga Din| 
Vera
  • 1.4k
  • 2
  • 15
  • 33