Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I have this code -

    echo "usage: <command> options:<w|l|h>"
while getopts wlh: option
    case $option in
print 'hi'$name

When I run bash getoptDemos.sh (without the option) it prints hi instead of calling the function usage. It calls usage when options other than w, h and l are given. Then can't it work when no options are specified.

I have tried using ?, \?, : in place of * but I can't achieve what I wanted to. I mean all the docs on getopt says it to use ?.

What am I doing wrong?

share|improve this question
What shell are you running it under? – Julian Oct 11 '12 at 8:52
I am running it under /bin/bash – Hussain Tamboli Oct 11 '12 at 8:55
Other alternatives: wiki.bash-hackers.org/howto/getopts_tutorial – slm Oct 2 '13 at 4:44
up vote 6 down vote accepted

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" ]

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)

share|improve this answer
no. its bash. So how do i achieve what I want - handle the no argument condition using bash. – Hussain Tamboli Oct 11 '12 at 8:59
If you want a mandatory option, I don't think thats possible - its probably why they are called options :) You can test $name though, after the loop to make sure it has been set. if [ -z "$name" ] ; then usage; exit ; fi – Julian Oct 11 '12 at 9:08
thanks. the above code really helped. Its too bad getopts doesn't have such provision. What's worse than that is can't upvote you. – Hussain Tamboli Oct 11 '12 at 9:14
what if I was running other shell? zsh, sh. does any shell other than bash take care of this condition? – Hussain Tamboli Oct 11 '12 at 10:30

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

share|improve this answer
thanks. +1 for you. when I put the last 3 lines from your code in sample.sh and run bash sample.sh -abc file.txt it gives - 1 non-option arguments. how do I find out how many options were given. (here 3) – Hussain Tamboli Oct 12 '12 at 5:14
Strange no one has commented on this slight bug -- if no options are given, OPTIND will be 1 after that 'while getopts ...' loop. Thus the if check should check equality with 1, not zero. – Daniel May 21 '15 at 22:07

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

if [[ ! $@ =~ ^\-.+ ]]

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

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.