我有一个通用库,用于在多个脚本中解析命令行选项,但是我也希望我的个人脚本也能够处理参数...例如common.sh:func...
我有一个通用库,用于从多个脚本解析命令行选项,但我还希望我的各个脚本也能够处理参数...例如
通用.sh:
function get_options {
echo -e "in getoptions"
echo $OPTIND
while getopts ":ab:" optionName; do
[ ... processing code ... ]
done
}
灰
. ./common.sh
function get_local_options {
echo -e "in getoptions"
echo $OPTIND
while getopts ":xy:" optionName; do
[ ... processing code ... ]
done
}
get_local_options $*
OPTIND=1
get_options $*
问题是,如果我用以下命令调用 a.sh:
a.sh -x -y foo -a -b bar
get_options 在 \'foo\' 处停止处理,因为它在第一个 \'非选项\' 处停止
有什么办法可以解决这个问题而不用自己重写吗?
我认为您需要让第一个 getopts 处理器构建一个它未处理的命令行元素列表。此外,它必须忽略 getopts 调用的返回值:getopts 可能返回非零值,因为它正在处理它不知道如何处理的命令行开关的参数。因此,第一个 getopts 处理器需要转到命令行的末尾。您不能相信它自己对选项何时停止以及参数何时开始的判断。(好吧,一旦您连续获得两个参数,您大概就可以跳过其余的参数,但我将把它留作练习。)
那么就像这样:
#!/bin/bash
UNHANDLED=()
function getxy {
while ((OPTIND<=$#)); do
if getopts ":xy:" opt; then
case $opt in
x|y) echo "getxy opt=$<$opt> OPTARG=<$OPTARG>";;
*) UNHANDLED+=(-$OPTARG);;
esac
else
UNHANDLED+=(${!OPTIND})
let OPTIND++
fi
done
}
function getab {
while getopts ":ab:" opt; do
case $opt in
a|b) echo "getab opt=$<$opt> OPTARG=<$OPTARG>";;
*) echo "getab * opt=<$opt> OPTARG=<$OPTARG>";;
esac
done
}
echo "--- getxy ---"
OPTIND=1
getxy "$@"
# now we reset OPTIND and parse again using the UNHANDLED array
echo "--- getab ---"
OPTIND=1
set -- "${UNHANDLED[@]}"
getab "$@"
# now we get remaining args
shift $((OPTIND-1))
for arg; do
echo "arg=<$arg>"
done