我正在尝试使用bash中的getopts处理命令行参数。其中一个要求是处理任意数量的选项参数(不使用引号)。
第一个例子(仅获取第一个参数)
madcap:~/projects$ ./getoptz.sh -s a b c
-s was triggered
Argument: a
第二个例子(我希望它表现得像这样但不需要引用参数“
madcap:~/projects$ ./getoptz.sh -s "a b c"
-s was triggered
Argument: a b c
有办法做到这一点吗?
这是我现在的代码:
#!/bin/bash
while getopts ":s:" opt; do
case $opt in
s) echo "-s was triggered" >&2
args="$OPTARG"
echo "Argument: $args"
;;
\?) echo "Invalid option: -$OPTARG" >&2
;;
:) echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
答案 0 :(得分:13)
我认为你想要的是从一个选项中获取值列表。为此,您可以根据需要多次重复该选项,并将其参数添加到数组中。
#!/bin/bash
while getopts "m:" opt; do
case $opt in
m) multi+=("$OPTARG");;
#...
esac
done
shift $((OPTIND -1))
echo "The first value of the array 'multi' is '$multi'"
echo "The whole list of values is '${multi[@]}'"
echo "Or:"
for val in "${multi[@]}"; do
echo " - $val"
done
输出结果为:
$ /tmp/t
The first value of the array 'multi' is ''
The whole list of values is ''
Or:
$ /tmp/t -m "one arg with spaces"
The first value of the array 'multi' is 'one arg with spaces'
The whole list of values is 'one arg with spaces'
Or:
- one arg with spaces
$ /tmp/t -m one -m "second argument" -m three
The first value of the array 'multi' is 'one'
The whole list of values is 'one second argument three'
Or:
- one
- second argument
- three
答案 1 :(得分:3)
您可以自己解析命令行参数,但不能将getopts
命令配置为识别单个选项的多个参数。 fedorqui's recommendation是一个不错的选择。
以下是一种自行解析选项的方法:
while [[ "$*" ]]; do
if [[ $1 = "-s" ]]; then
# -s takes three arguments
args="$2 $3 $4"
echo "-s got $args"
shift 4
fi
done
答案 2 :(得分:2)
这是我使用用户定义函数执行此操作的方式:getopts-extra
。
function getopts-extra () {
declare i=1
# if the next argument is not an option, then append it to array OPTARG
while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
OPTARG[i]=${!OPTIND}
let i++ OPTIND++
done
}
# Use it within the context of `getopts`:
while getopts s: opt; do
case $opt in
s) getopts-extra "$@"
args=( "${OPTARG[@]}" )
esac
done
getoptz.sh 的完整示例:
#!/usr/bin/env bash
function getopts-extra () {
declare i=1
# if the next argument is not an option, then append it to array OPTARG
while [[ ${OPTIND} -le $# && ${!OPTIND:0:1} != '-' ]]; do
OPTARG[i]=${!OPTIND}
let i++ OPTIND++
done
}
function main () {
declare args
declare OPTIND OPTARG opt
while getopts :s: opt; do
case $opt in
s) getopts-extra "$@"
args=( "${OPTARG[@]}" )
;;
\?) echo "Invalid option: -$OPTARG" >&2
;;
:) echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
declare i
for i in "${!args[@]}"; do
echo "args[$i]: ${args[i]}"
done
}
main "$@"
exit
测试:
bash getoptz.sh -s a b c
输出:
args[0]: a
args[1]: b
args[2]: c
此函数是名为 xsh-lib/core 的 bash 库的一部分,可在语法 xsh /util/getopts/extra
处使用。