3

This question already has an answer here:

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

marked as duplicate by jimmij, Stephen Rauch, John, Archemar, Christopher Dec 15 '17 at 15:38

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.

  • Out of curiosity, what's this used for? It's unusual for options to work this way. – Mikel Mar 21 '14 at 13:31
3

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$]
  • I don't understand the reason for the downvote on this answer, it appears to work fine and be fairly sustainable. If you are considering downvoting, please at least state why so that the answer can be improved. – Chris Down Apr 27 '13 at 8:18
  • @ChrisDown Is this comment directed to a specific user? – Rany Albeg Wein Apr 27 '13 at 8:23
  • Yes, this answer was downvoted, but I can't see why. – Chris Down Apr 27 '13 at 8:24

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