4

I am trying to process command line arguments using getopts in bash. One of the requirements is for the processing of an arbitrary number of option arguments (without the use of quotes).

1st example (only grabs the 1st argument)

madcap:~/projects$ ./getoptz.sh -s a b c
-s was triggered
Argument: a

2nd example (I want it to behave like this but without needing to quote the argument"

madcap:~/projects$ ./getoptz.sh -s "a b c"
-s was triggered
Argument: a b c

Is there a way to do this?

Here's the code I have now:

#!/bin/bash
while getopts ":s:" opt; do
    case $opt in
    s) echo "-s was triggered" >&2
       args="$OPTARG"
       echo "Argument: $args"
       ;;
       \?) echo "Invalid option: -$OPTARG" >&2
       ;;
    :) echo "Option -$OPTARG requires an argument." >&2
       exit 1
       ;;
    esac
done

Note that I want to support multiple flags this way, e.g.

madcap:~/projects$ ./getoptz.sh -s a b c -u 1 2 3 4
-s was triggered
Argument: a b c
-u was triggered
Argument: 1 2 3 4
Mikel
  • 56,387
  • 13
  • 130
  • 149
user1117603
  • 141
  • 1
  • 2

1 Answers1

4

I think that the best way to go is using -s for each argument, i.e. -s foo -s bar -s baz, but if you still want to support several arguments for a single option, I suggest you to not use getopts.

Please take a look at the following script:

#!/bin/bash

declare -a sargs=()

read_s_args()
{
    while (($#)) && [[ $1 != -* ]]; do sargs+=("$1"); shift; done
}

while (($#)); do
    case "$1" in
        -s) read_s_args "${@:2}"
    esac
    shift
done

printf '<%s>' "${sargs[@]}"

When -s is being detected, read_s_args is invoked with the remaining options and arguments on the command line. read_s_args reads its arguments until it reaches the next option. Valid arguments to -s are being stored in the sargs array.

Here is a sample output:

[rany$] ./script -s foo bar baz -u a b c -s foo1 -j e f g
<foo> <bar> <baz> <foo1>
[rany$]
Rany Albeg Wein
  • 670
  • 4
  • 14