How can I detect that no options were passed with getopts?

getopts processes the options in turn. That's its job. If the user happens to pass no option, the first invocation of getopts exits the while loop.

If none of the options take an argument, the value of OPTIND indicates how many options were passed. In general, OPTIND is the number of arguments that are options or arguments to options, as opposed to non-option arguments (operands).

while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"

In any case, you're not trying to determine whether there were no options, but whether none of the name-setting options were passed. So check if name is unset (and take care to unset it first).


When you run this script without any options, getopt will return false, so it won't enter the loop at all. It will just drop down to the print - is this ksh/zsh?

If you must have an option, you're best bet is to test $name after the loop.

if [ -z "$name" ]
then
   usage
   exit
fi

But make sure $name was empty before calling getopts (as there could have been a $name in the environment the shell received on startup) with

unset name

(before the getopts loop)


If your script must receive option arguments is any case, place this block in the beginning (before getops).

if [[ ! $@ =~ ^\-.+ ]]
then
  #display_help;
fi

Block checks that parameter string not begins with - symbol, what indicates that first parameter is not an option argument.