문제

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!

도움이 되었습니까?

해결책

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.

다른 팁

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).

Setting OPTIND=1 may not work reliably on zsh. Try to use something different than getopts:

while [ "$#" -gt 0 ]
do
   case "$1" in
   -h|--help)
      help
      return 0
      ;;
   -o|--option)
      option
      return 0
      ;;
   -*)
      echo "Invalid option '$1'. Use -h|--help to see the valid options" >&2
      return 1
      ;;
   *)
      echo "Invalid option '$1'. Use -h|--help to see the valid options" >&2
      return 1
   ;;
   esac
   shift
done
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top