views:

5821

answers:

2

Say I have a script that gets called with this line:

./myscript -vfd ./foo/bar/someFile -o /fizz/someOtherFile

or this one:

./myscript -v -f -d -o /fizz/someOtherFile ./foo/bar/someFile

What's the accepted way of parsing this such that in each case (or some combination of the two) $v $f $d will all be set to true and $outFile will be equal to "/fizz/someOtherFile"?

+6  A: 

Consider getopt (1).

From the man page:

SYNOPSIS args=getopt optstring $* ; errcode=$?; set -- $args

DESCRIPTION The getopt utility is used to break up options in command lines for easy parsing by shell procedures, and to check for legal options...

and further down:

This code will accept any of the following as equivalent:

       cmd -aoarg file file
       cmd -a -o arg file file
       cmd -oarg -a file file
       cmd -a -oarg -- file file
dmckee
In most sources which talk about unix command line parsing, the use of `getopt` is not advised due to its bugs and shortcomings. The internal `getopts` command in bash should be used instead, or, if parsing of GNU-style long options is needed, a custom loop is often suggested.
akaihola
+12  A: 

getopt()/getopts() is a good option. Stolen from here:

The simple use of "getopt" is shown in this mini-script:

#!/bin/bash
echo "Before getopt"
for i
do
  echo $i
done
args=`getopt abc:d $*`
set -- $args
echo "After getopt"
for i
do
  echo "-->$i"
done

What we have said is that any of -a, -b, -c or -d will be allowed, but that -c is followed by an argument (the "c:" says that).

If we call this "g" and try it out:

bash-2.05a$ ./g -abc foo
Before getopt
-abc
foo
After getopt
-->-a
-->-b
-->-c
-->foo
-->--

We start with two arguments, and "getopt" breaks apart the options and puts each in its own argument. It also added "--".

Matt J