use*_*603 6 unix linux bash shell getopts
我试图在bash中使用getopts处理命令行参数.其中一个要求是处理任意数量的选项参数(不使用引号).
第一个例子(只抓住第一个参数)
madcap:~/projects$ ./getoptz.sh -s a b c
-s was triggered
Argument: a
Run Code Online (Sandbox Code Playgroud)
第二个例子(我希望它表现得像这样但不需要引用参数"
madcap:~/projects$ ./getoptz.sh -s "a b c"
-s was triggered
Argument: a b c
Run Code Online (Sandbox Code Playgroud)
有没有办法做到这一点?
这是我现在的代码:
#!/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
Run Code Online (Sandbox Code Playgroud)
miv*_*ivk 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
Run Code Online (Sandbox Code Playgroud)
输出将是:
$ /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
Run Code Online (Sandbox Code Playgroud)
这是我使用用户定义函数执行此操作的方法: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
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
测试:
bash getoptz.sh -s a b c
Run Code Online (Sandbox Code Playgroud)
输出:
args[0]: a
args[1]: b
args[2]: c
Run Code Online (Sandbox Code Playgroud)
该函数是名为xsh-lib/core的 bash 库的一部分,可在 语法 中找到xsh /util/getopts/extra。
您可以自己解析命令行参数,但getopts无法将命令配置为识别单个选项的多个参数。fedorqui 的推荐是一个不错的选择。
这是您自己解析选项的一种方法:
while [[ "$*" ]]; do
if [[ $1 = "-s" ]]; then
# -s takes three arguments
args="$2 $3 $4"
echo "-s got $args"
shift 4
fi
done
Run Code Online (Sandbox Code Playgroud)