Bash / Parsing options

From WhyNotWiki
Jump to: navigation, search



man 1 getopt:

       getopt  is used to break up (parse) options in command lines for easy parsing by shell procedures, and to check for legal options.  It uses the GNU
       getopt(3) routines to do this.



# Note that we use `"$@"' to let each command-line parameter expand to a 
# separate word. The quotes around `$@' are essential!
# We need TEMP as the `eval set --' would nuke the return value of getopt.
TEMP=`getopt -o ab:c:: --long a-long,b-long:,c-long:: \
     -n 'example.bash' -- "$@"`

if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi

# Note the quotes around `$TEMP': they are essential!
eval set -- "$TEMP"

while true ; do
    case "$1" in
        -a|--a-long) echo "Option a" ; shift ;;
        -b|--b-long) echo "Option b, argument \`$2'" ; shift 2 ;;
            # c has an optional argument. As we are in quoted mode,
            # an empty parameter will be generated if its optional
            # argument is not found.
            case "$2" in
                "") echo "Option c, no argument"; shift 2 ;;
                *)  echo "Option c, argument \`$2'" ; shift 2 ;;
            esac ;;
        --) shift ; break ;;
        *) echo "Internal error!" ; exit 1 ;;
echo "Remaining arguments:"
for arg do echo '--> '"\`$arg'" ; done

getopts builtin vs. getopt command Retrieved on 2007-05-11 11:18.

You should look at the 'getopt' command. It exists to help in parsing options to scripts. There is also a bash 'getopts' built-in. But the getopt command can handle the long --option form. The getopts built-in handles only single-character options.

Error on call to Template:cite web: Parameter url must be specified. Retrieved on 2007-05-11 11:18.



This is a standalone executable that has been around a long time. Older versions lack the ability to handle quoted arguments (foo a "this won't work" c) and the versions that can do so clumsily. If you are running a recent Linux version, your "getopt" can do that; SCO OSR5, Mac OS X 10.2.6 and FreeBSD 4.4 has an older version that does not.


[It's a] sh and bash builtin. Easier to use and generally better than getopt [...].

This works rather differently than "getopt". First, because it's a built-in, you usually won't find a separate man page for it, though "help getopts" may give you what you need.

The old "getopt" is called once, and it modifies the environment as we saw above. The builtin "getopts" is called each time you want to process an argument, and it doesn't change the original arguments .

What does it do?

It takes a command line string with a mix of options and other arguments and re-arranges them so that they can easily be processed by a bash while/case/esac loop...

For example, this:

--from CREATE TABLE `ticket_flags_to_agents` out.sql --until UNLOCK

becomes [canonicalized] as this:

--from CREATE TABLE `ticket_flags_to_agents` --until UNLOCK -- out.sql

It also generates errors if it encounters an option that you don't claim to support, or if an option that requires a parameter is missing that parameter, etc.

Problem: Doesn't work right unless you have at least one short option!

This doesn't work the way you'd expect it to:

echo $@
TEMP=`getopt --long from:,until: -n $0 -- "$@"`
eval set -- "$TEMP"
echo $@
$ ./script --from a
--from a
a --

You have to pass the -o option (or understand and use the default behavior when you omit it).

This works correctly:

echo $@
TEMP=`getopt -o q --long from:,until: -n $0 -- "$@"`
eval set -- "$TEMP"
echo $@
$ ./script --from a
--from a
--from a --

What if you don't want any short options? Too bad, I guess!


Personal tools