I defined the function f
in Bash based on the example here (under "An option with an argument"):
f () {
while getopts ":a:" opt; do
case $opt in
a)
echo "-a was triggered, Parameter: $OPTARG" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
return 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
return 1
;;
esac
done
}
Whereas they use a script, I directly define the function in the shell.
When I first launch Bash and define the function, everything works: f -a 123
prints -a was triggered, Parameter: 123
. But when I run the exact same line a second time, nothing is printed.
What's causing this behavior? It happens in Bash 3.2 and 4.3, but it works fine in Zsh 5.1. This is surprising because the example was supposed to be for Bash, not for Zsh.
Best Answer
bash getopts use an environment variable OPTIND to keep track the last option argument processed. The fact that
OPTIND
was not automatically reset each time you calledgetopts
in the same shell session, only when the shell was invoked. So from second time you calledgetopts
with the same arguments in the same session,OPTIND
wasn't changed,getopts
thought it had done the job and do nothing.You can reset
OPTIND
manually to make it work:or just put the function into a script and call the script multiple times.
zsh getopts is slightly different.
OPTIND
was normally reset to 1 each time upon exit from shell function.