views:

412

answers:

2

I have a bash script that uses getopt to parse its parameters. It correctly handles switches and long options, as well as arguments and quoted arguments, but I cannot figure out how to iterate over the options/arguments string returned by the backticks. Something like:

params=`getopt -o ab -l ccc  -- "$@"`
echo $params
for param in "$params"
do
echo $param
done

Will echo out -a -- 'foo' 'foo bar' when the script is invoked as ./a.sh -a foo "foo bar", but the loop rather than iterating over each separately will only run once over the entire string. Removing the double quotes:

for param in $params

will cause it to iterate like this:

-a
--
'foo'
'foo
bar'

ignoring the quoting around "foo bar". Is there a simple way to fix this?

+1  A: 

From the getopt manpage (at least the util-linux one:)

Traditional implementations of getopt(1) are unable to cope with whitespace and other (shell-specific) special characters in arguments and non-option parameters. To solve this problem, this implementation can generate quoted output which must once again be interpreted by the shell (usually by using the eval command). This has the effect of pre‐ serving those characters, but you must call getopt in a way that is no longer compatible with other versions (the second or third format in the SYNOPSIS). To determine whether this enhanced version of getopt(1) is installed, a special test option (-T) can be used.

Example:

$ getopt -- 'abc' -a -b 'foo bar' -c
-a -b -c -- 'foo bar'

So, you can see the output is quoted, ready to be used:

$ eval set -- "`getopt -- 'abc' -a -b 'foo bar' -c`"
$ for a; do echo "arg: $a"; done
arg: -a
arg: -b
arg: -c
arg: --
arg: foo bar
derobert
A: 

Take a look at the bash builtin getopts.

Also, for a nice example of using getopt, see this script.

Dennis Williamson