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?
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
Take a look at the bash
builtin getopts
.
Also, for a nice example of using getopt
, see this script.