Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bug in parsing args with getopts in bash

Tags:

bash

getopts

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!

like image 821
udiboy1209 Avatar asked May 10 '14 13:05

udiboy1209


2 Answers

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.

like image 157
udiboy1209 Avatar answered Oct 16 '22 14:10

udiboy1209


When you source a script, the arguments parsed by getopts are those of the current shell, not the parameters on the source command line.

The common workaround is to have your script merely print the path, and invoke it like cd "$(bd)" instead (perhaps indirectly through a function or alias).

like image 42
tripleee Avatar answered Oct 16 '22 13:10

tripleee