'getopts & preventing accidentally interpreting short options as arguments
Here's a toy example that shows what I mean:
while getopts "sf:e:" opt; foundOpts="${foundOpts}${opt}" ; done
echo $foundOpts
problem is that getopts
isn't particularly smart when it comes to arguments. for example, ./myscript.sh -ssssf
will output option requires an argument -- f
. That's good.
But if someone does ./myscript.sh -ssfss
by mistake, it parses that like -ss -f ss
, which is NOT desirable behavior!
How can I detect this? Ideally, I'd like to force that f
parameter to be defined separately, and allow -f foo
or -f=foo
, but not -sf=foo
or -sf foo
.
Is this possible without doing something hairy? I imagine I could do something with a RegEx, along the lines of match $@
against something like -[^ef[:space:]]*[ef]{1}[ =](.*)
, but I'm worried about false positives (that regex might not be exactly right)
Thanks!
Solution 1:[1]
Here's what I've come up with. It seems to work, but I imagine the RegEx could be simplified. And I imagine there are edge cases I've overlooked.
validOpts="sf:e:"
optsWithArgs=$(echo "$validOpts" | grep -o .: | tr -d ':\n')
# ensure that options that require (or have optional) arguments are not combined with other short options
invalidOptArgFormats=( "[^$optsWithArgs[:space:]]+[$optsWithArgs]" "[$optsWithArgs]([^ =]|[ =]$|$)" )
IFS="|" && invalidOptArgRegEx="-(${invalidOptArgFormats[*]})"
[[ "$@" =~ $invalidOptArgRegEx ]] && echo -e "An option you provided takes an argument; it is required to have its option\n on a separate - to prevent accidentally passing an opt as an argument.\n (You provided ${BASH_REMATCH[0]})" && exit 1
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | user3534080 |