Sep 182012
 

Today i was writing a bash script that should manage some input arguments, and so i studied getopt, this is a convenient and elegant way to manage input parameters in a bash script. With it you can define switch (present or not) or parameters with an option, thus making your simple bash script much more professional.

Let’s see how to use this command and its options.

Please note that on Linux there are two different ways of parsing command line arguments. 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). In this article I’ll talk of the first one, after some problems with script not working in dash i prefer to use external small programs rather than bash built-in commands.




In Debian and Ubuntu the command getopt is contained in the package util-linux that is automatically installed, i expect that also on other Linux distribution you find it without any need of installing additional packages.

Basic usage

In getopt the parameters are parsed from left to right. Each parameter is classified as a short option, a long option, an argument to an option, or a non-option parameter.

A simple short option is a `-‘ followed by a short option character. If the option has a required argument, it may be written directly after the option character or as the next parameter (ie. separated by whitespace on the command line). If the option has an optional argument, it must be written directly after the option character if present.

It is possible to specify several short options after one `-‘, as long as all (except possibly the last) do not have required or optional arguments.

A long option normally begins with `–‘ followed by the long option name. If the option has a required argument, it may be written directly after the long option name, separated by `=’, or as the next argument (ie. separated by whitespace on the command line). If the option has an optional argument, it must be written directly after the long option name, separated by `=’, if present . Long options may be abbreviated, as long as the abbreviation is not ambiguous.

In my opinion the best way to present the command is with an example.

I want a script that can take the short option -h -1 -2 and -3 with an argument, like -3=Hello, and that can also manage the following long options –help, –one, –two and –three with an argument.

#!/bin/bash
 
# Execute getopt on the arguments passed to this program, identified by the special character $@
PARSED_OPTIONS=$(getopt -n "$0"  -o h123: --long "help,one,two,three:"  -- "$@")
 
#Bad arguments, something has gone wrong with the getopt command.
if [ $? -ne 0 ];
then
  exit 1
fi
 
# A little magic, necessary when using getopt.
eval set -- "$PARSED_OPTIONS"
 
 
# Now goes through all the options with a case and using shift to analyse 1 argument at a time.
#$1 identifies the first argument, and when we use shift we discard the first argument, so $2 becomes $1 and goes again through the case.
while true;
do
  case "$1" in
 
    -h|--help)
      echo "usage $0 -h -1 -2 -3 or $0 --help --one --two --three"
     shift;;
 
    -1|--one)
      echo "One"
      shift;;
 
    -2|--two)
      echo "Dos"
      shift;;
 
    -3|--three)
      echo "Tre"
 
      # We need to take the option of the argument "three"
      if [ -n "$2" ];
      then
        echo "Argument: $2"
      fi
      shift 2;;
 
    --)
      shift
      break;;
  esac
done



The options we have used with getopt in this example are:

-l, –longoptions (longopts)
The long (multi-character) options to be recognized. More than one option name may be specified at once, by separating the names with commas. This option may be given more than once, the longopts are cumulative. Each long option name in longopts may be followed by one colon to indicate it has a required argument, and by two colons to indicate it has an optional argument.

-o, –options (shortopts)
The short (one-character) options to be recognized. If this option is not found, the first parameter of getopt that does not start with a `-‘ (and is not an option argument) is used as the short options string. Each short option character in shortopts may be followed by one colon to indicate it has a required argument, and by two colons to indicate it has an optional argument.

Conclusions

if you look at the example you can see that is longer to describe how getopt work than using it, you just need to define the short and long list of options and than manage them with a while loop and a case, and you’ll have a bash script that can smartly manage options.

Popular Posts:

Flattr this!

  3 Responses to “Parse options in your bash script with getopt”

  1. Thank you for the useful tip.

    A minor correction:
    ‘-h|–help’ should be ‘-h|–help)’

  2. I’ve been writing bash scripts for years, and I’ve never heard of getopt (or getopts) before. getopt seems very simple to use, and as you said, makes the script accept input parameters just like any other professional program would, which is awesome. Thanks for sharing – your article is very easy to follow, and your example is awesome – I’m adding this to my Linux notes folder that I always reference.

    BTW, you’re missing a ‘)’ after ‘-h|–help’.
    Also, while your script works perfectly on Debian (and many other distributions I’m sure), OS X doesn’t seem to like it 🙂

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)

*