Getopt in Bash

There are two different ways of parsing command line arguments while using getopt(3). There is an utility called getopt (man 1 getopt). This utility is available in all shells. Then in bash, there is another built-in tool for parsing arguments called getopts (it’s a built-in, so it doesn’t have it’s own man-page — try help getopts).


Here’s an example script that demonstrates the usage of getopt:


# Execute getopt
ARGS=`getopt -o "123:" -l "one,two,three:" \
      -n "" -- "$@"`

#Bad arguments
if [ $? -ne 0 ];
  exit 1

# A little magic
eval set -- "$ARGS"

# Now go through all the options
while true;
  case "$1" in
      echo "Uno"

      echo "Dos"

      echo "Tres"

      # We need to take the option argument
      if [ -n "$2" ];
        echo "Argument: $2"
      shift 2;;


At first, the getopt utility is called with desired parameters (see man getopt for detailed description of all the options). If it returns anything else than 0, something was wrong and we’ll end the script. There is no error message necessary, because the getopt itself will inform user about what went wrong.

After that, there’s a little magic line with eval and set. It’s there to preserve whitespaces inside options arguments. Detailed description of this technique is here.

All options are evaluated and appropriate actions take place in the while loop at the end of the script.


Here’s an example script that demonstrates the usage of getopts:


while getopts "123:" OPTION
  case $OPTION in
    1)  echo "Uno";;
    2)  echo "Dos";;
    3)  echo "Tres: $OPTARG";;

    # Unknown option. No need for an error, getopts informs
    # the user itself.
    \?) exit 1;;

As you can see, the bash built-in version is easier to use, but it can’t handle long options like --option.


Which one you should use? Well, it’s up to you, what you need. If you’re looking for compatibility of your script among more shells than just bash or want to have long options, you’ll need to use the getopt utility. If not, I’d go for the getopts built-in, which I personally consider more user-friendly.


If you liked this post, make sure you subscribe to receive notifications of new content by email or RSS feed.
Alternatively, feel free to follow me on Twitter or Google+.

One comment

  1. Keegan Witt

    Very helpful, thank you!
    For those wondering, you can leave off as many short or long options as you want (the relationship doesn’t have to be 1 to 1 between short and long options), You can even have no short options, but you will still need the -o “”.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s