Iterating over options and quoted/unquoted argumen

2019-07-18 00:18发布

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?

标签: bash shell
2条回答
Anthone
2楼-- · 2019-07-18 00:31

Take a look at the bash builtin getopts.

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

查看更多
放我归山
3楼-- · 2019-07-18 00:44

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
查看更多
登录 后发表回答