I am using a bash function to which I pass arguments. I would like to capture if a particular option was defined by the user -v NUM or --verbosity=NUM. If defined as described, I would like to set tho local variable vb to NUM.
1 Answer
I'll start by saying that a blind scan of the arguments like that would fail to find all the valid ways the verbosity is to be specified if we assume the aim is to accept GNU-style long options.
What if the user passes -xyv3 (same as -x -y -v 3) or --output -v2 (same as --output=-v2, where -v2 is the argument to the --output option) or cmd -x -- foo bar -v baz (where -v is not to be treated as an option), or --verb=12 (abbreviation as supported in GNU option style parsing)? getopt / getopts are there to help you parse options properly.
But if you don't care about proper option parsing, and can rely on the user always passing the -v / --verbosity option like that and not passing those strings as non-option arguments otherwise, you could do:
extract_verbosity() {
unset -v REPLY
while [ "$#" -gt 0 ]; do
case "$1" in
(-v)
[ "$#" -gt 1 ] || break
shift; REPLY=$1
;;
(--verbosity=*)
REPLY=${1#*=}
esac
shift
done
[ -n "${REPLY+set}" ]
}
and then in your function:
my_function() {
verbosity=0 # default
extract_verbosity "$@" && verbosity=$REPLY
...
}
-
Why not use -v, -vv, -vvv as different (but similar) cases (unless you need an immense range of verbosities)? You could still have a long-form
--verbosity=NUMJeremy Boden– Jeremy Boden2021-08-04 16:32:28 +00:00Commented Aug 4, 2021 at 16:32 -
Once you perform the argument shift, can one reset
$@back to its original values ?Isabel– Isabel2021-08-04 16:35:07 +00:00Commented Aug 4, 2021 at 16:35 -
After calling getopt, should I first check for errors (using
#?) or check the parameters nevertheless ? And only then issue the error messages? My current problem is that the error message is dependent on the verbosity level.Isabel– Isabel2021-08-04 16:45:07 +00:00Commented Aug 4, 2021 at 16:45 -
@Isabel,
extract_verbosityprocesses it's own list of arguments (which is the same asmy_function's asmy_functioncalled it with"$@"). It leaves its caller's list of arguments untouched.Stéphane Chazelas– Stéphane Chazelas2021-08-04 19:46:27 +00:00Commented Aug 4, 2021 at 19:46 -
@isabel, yes, you'd typically do
code="set -- $(getopt...)" || { usage; exit 1; }; eval "$code"Stéphane Chazelas– Stéphane Chazelas2021-08-04 19:52:16 +00:00Commented Aug 4, 2021 at 19:52
bash. If on Linux, you can have a look at thegetoptcommand fromutil-linux. You'll find several Q&As discussing it here. If not on Linux, see my github.com/stephane-chazelas/misc-scripts/blob/master/… (for sh but would work as well for bash).#@and setvbthat way. Nogetopts,getoptor anything.-xyv3(same as-x -y -v 3) or--output -v2(same as--output=-v2, where-v2is the argument to the--outputoption) orcmd -x -- foo bar -v baz(where-vis not to be treated as an option), or--verb=12(abbreviation as supported in GNU option style parsing)?getopt/getoptsare there to help you parse options properly.