2

This question already has an answer here:

how can I make getopts take 2 arguments after -h option? I mean it is supposed to be saved in array but either it doesn't work, or I am making mistake by writing it down like this: echo " ${array[1]} ${array[2]}"

 OPTIND=1 
    hh=
    while getopts "h:" flag
    do
    case "$flag" in
    h)
    hh=($OPTARG)  ;;
   esac
   done
   shift "$((OPTIND-1))"

marked as duplicate by jimmij, roaima, Stephen Rauch, John, ilkkachu Dec 15 '17 at 15:29

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

3

This is not possible. What you can do is to pass the two arguments quoted and separated by an appropriate delimiter and split OPTARG to obtain the two parts.

Examples of possible calling syntaxes are:

prog -h part1:part2

prog -h "part1 part2"

And in your case statement you can split the components by, e.g. in case of a colon delimiter:

p1=${OPTARG%:*} p2=${OPTARG#*:}

Edit (to clarify): An "appropriate delimiter" is one that is not part of the individual part1/part2 components (thus unique in the composite OPTARG), so that the splitting is unambiguous.

2

One way to do it would be to pass -h several times:

OPTIND=1 
hh=()
while getopts h: flag; do
  case "$flag" in
    h) hh+=("$OPTARG");;
  esac
done
shift "$((OPTIND-1))"

And call it as:

myscript -h host1 -h host2...
0

Short answer: getopts is not intended to be used like this.

Long answer: you could try something like this (untested), but getopts won't be able to do syntax checking:

OPTIND=1 
hh=()
args=( "$@" )
while getopts "h:" flag; do
  case "$flag" in
  h)
    hh=("$OPTARG" "${args[$OPTIND]}")
    $((OPTIND++))
    ;;
  esac
done
shift "$((OPTIND-1))"

If you go down this path, you'd need to add your own error handling for e.g. the 2nd arg doesn't exist/is empty/looks like an option instead of an argument.

Not the answer you're looking for? Browse other questions tagged or ask your own question.