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