1

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))"
anonym
  • 11
  • 2

3 Answers3

2

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.

Janis
  • 14,014
  • 3
  • 25
  • 42
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...
Stéphane Chazelas
  • 522,931
  • 91
  • 1,010
  • 1,501
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.

Mikel
  • 56,387
  • 13
  • 130
  • 149