I'm writing a simple bash script that takes one optional parameter (-t ) followed by some number of additional arguments.
I was thinking getopts would be a reasonable way to achieve this, but I'm having difficulty getting the desired behavior. What I have is the following:
foo() {
baz=10
while getopts ":t:" option; do
case "$option" in
t) baz=$OPTARG ;;
esac
done
shift $((OPTIND - 1))
bar -t $baz $1 $2 $3
}
The problem is that $OPTIND
does not seem to vary depending on whether the argument is present, so I don't get the correct behavior as expected with an optional parameter (i.e., I can't get shift to shift the right number of arguments regardless of whether the argument is there).
I want both of the following to execute correctly:
foo a b c
foo -t 5 a b c
What's the easiest way to achieve this? I'd prefer a solution that isn't a hack since I may want to use additional optional parameters.
The problem is that you're never resetting $OPTIND
, so each time you call foo
it examines its arguments starting after the last processed option-index. For example:
# $OPTIND is now 1
foo -t opt arg1 arg2 arg3
# the above recognizes -t opt as an option, and sets $OPTIND to 3
# $OPTIND is now 3
foo arg4 arg5 arg6
# the above recognizes that arg6 is not an option, so it leaves $OPTIND at 3
The solution is to localize $OPTIND
within foo
, explicitly setting it to 1
:
foo() {
baz=10
local OPTIND=1
while getopts ":t:" option; do
case "$option" in
t) baz=$OPTARG ;;
esac
done
shift $((OPTIND - 1))
bar -t $baz $1 $2 $3
}
(You probably want to localize $baz
as well, while you're at it.)
It appears that you're trying to write a bash function, not a bash script. OPTIND is set to 1 when the shell/script is invoked, but not when a function is invoked, so subsequent function calls with different arguments would continue parsing at the same point.
If you want to keep it as a function, you can reset it manually:
foo() {
OPTIND=1
baz=10
while getopts ":t:" option; do
case "$option" in
t) baz=$OPTARG ;;
esac
done
echo $OPTIND
shift $((OPTIND - 1))
echo bar -t $baz $1 $2 $3
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With