Search code examples
bashgetopts

Bug in parsing args with getopts in bash


I was trying to modify the bd script to use getopts. I am a newbie at bash scripting

my script is

while getopts ":hvis:d:" opt
do
...
done

...

echo $somedirpath
cd "$somedirpath"    

this runs fine when doing

$ ./bd -v -i -s search

or

$ ./bd -is search -d dir

But when running it like this

$ . ./bd -s search

getopts doesn't read the arguments at all. And all the variables I set in the while loop according to the arguments are all not set, so the script no longer works. Please help!


Solution

  • Setting OPTIND=1 before invoking getopts works fine.

    The problem is that getopts relies on OPTIND to loop through the arguments provided, and after sourcing the script, it will be set to some value greater than 1 by getopts according to how many arguments you pass. This value gets carried over even after the script ends(because its being sourced). So the next time its sourced, getopts will pick up from that OPTIND, rather than starting from 1!

    This might cause strange behaviour with other scripts, and I don't know how safe this is. But it works!

    For a better workaround, I think what @tripleee suggests looks safe and robust.