Search code examples
bashshellcommand-line-argumentsgetopts

Running a script with getopts works the first time, but doesn't work the second time I run it


This is my script. I adapted it from this tutorial so it can't be an error in the script itself. (The original script had the same problem.)

#!/bin/bash

while getopts "a:" opt; do
  case $opt in
    a)
      echo "-a was triggered, Parameter: $OPTARG"
      ;;
  esac
done

Here's my output:

bash-3.2$ source getopt.sh
bash-3.2$ source getopt.sh -a /dev/null
-a was triggered, Parameter: /dev/null
bash-3.2$ source getopt.sh -a /dev/null
bash-3.2$ 

I've combed the Internet and can't find any explanation for this behavior.


Solution

  • source runs the bash commands in the indicated file within the execution context of the current shell. That execution context includes the variable OPTIND which getopts uses to remember the "current" argument index. So when you repeatedly source the script, each invocation of getopts starts at the argument index after the last argument processed by the previous invocation.

    Either reset OPTIND to 1 at the beginning of the script or invoke the script with bash getopt.sh. (Normally getopts is invoked as part of a script which is run through a she-bang execution, so it has its own execution context and you don't have to worry about its variables.)