使用 getopts (bash) 的多个选项参数
Posted
技术标签:
【中文标题】使用 getopts (bash) 的多个选项参数【英文标题】:Multiple option arguments using getopts (bash) 【发布时间】:2013-04-17 16:10:07 【问题描述】:我正在尝试在 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
【问题讨论】:
这可能会有所帮助:***.com/a/7530327/1983854 需要更多细节。当给定getoptz.sh -s a -b c
时,你想要什么行为? -b
是 -s
的参数,还是 -
表示新选项?
与Calling different programs with different options and different arguments for each option 相关但绝不重复。一般最好使用标准的命令界面指南POSIX Utility Conventions
【参考方案1】:
我认为您想要的是从单个选项中获取值列表。为此,您可以根据需要多次重复该选项,并将其参数添加到数组中。
#!/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
【讨论】:
【参考方案2】:您可以自己解析命令行参数,但不能将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
【讨论】:
确实,“识别单个选项的多个参数”是不可能的,但可以重复该选项。我在答案中添加了一个示例,因为我认为这才是真正想要的。【参考方案3】:这是我使用用户定义函数执行此操作的方法: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
。
【讨论】:
以上是关于使用 getopts (bash) 的多个选项参数的主要内容,如果未能解决你的问题,请参考以下文章