I have the following script that I call from my .bash_profile
:
# Set directories based on current path
__set_dirs() {
currdir=`pwd`
if [[ ${currdir} =~ "\/path\/to\/main\/(.*)\/working\/([a-z]+)(/?.*)" ]]
then
ws=${BASH_REMATCH[1]}
subdirs=${BASH_REMATCH[3]}
stgdir=${ts}/${ws}/STAGING${subdirs}
else
echo "${currdir} is not a workspace"
stgdir=""
fi
}
# Update local version with staging version
upd() {
__set_dirs
if [[ -n ${stgdir} ]]
then
__overwrite=0
while getopts "o" opt
do
case $opt in
o)
__overwrite=1
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done
echo "Updating ${currdir} with latest from ${stgdir}..."
if [ ${__overwrite} -eq 0 ]
then
update -r ${stgdir} ${currdir}
else
echo "Overwriting all local changes!"
update -r -w ${stgdir} ${currdir}
fi
fi
unset __overwrite
}
When I execute
> upd -o
The flag is completely ignored--I never see the message "Overwriting all local changes!". Have I missed something somewhere?
UPDATE: It does work, but only the first time I run the script. From the second time on, the flag gets ignored.
All right, figured it out:
After rifling through the man page for getopts
, I found this tidbit (emphasis mine):
Each time it is invoked, getopts places...the index of the next argument to be processed into the variable OPTIND. OPTIND is initialized to 1 each time the shell or a shell script is invoked.... The shell does not reset OPTIND automatically; it must be manually reset between multiple calls to getopts within the same shell invocation if a new set of parameters is to be used.
Since I only run the script once from by .bashrc, OPTIND
only gets initialized once. The first time I run the function, everything's hunky dory. The second time on, OPTIND
is set to 2 and getopts
doesn't find anything there, so it moves on.
Armed with this knowledge, I modified upd()
to reset OPTIND
to 1:
upd() {
__set_dirs
if [[ -n ${stgdir} ]]
then
__overwrite=0
OPTIND=1
while getopts "o" opt
...
That fixed it. OPTIND
: more important than you'd think.