我正在尝试在bash中使用getopts来解析命令行参数,但如果没有匹配参数(或者没有给出cmdline参数),我无法弄清楚如何实现“默认”操作。
这是我迄今为止尝试过的简化版本:
while getopts v:t:r:s:c: name;
do
case $name in
v) VALIDATE=1;;
t) TEST=1;;
r) REPORT=1;;
s) SYNC=1;;
c) CLEAR=1;;
*) print_help; exit 2;;
\?) print_help; exit 2;;
esac
done
是否有任何(简单)方法可以调用print_help; 2号出口;在非匹配输入?
答案 0 :(得分:4)
查看您的问题和Aditya答案的评论,我建议如下:
[getopts]$ cat go
#!/bin/bash
function print_help { echo "Usage" >&2 ; }
while getopts vtrsc name; do
case $name in
v) VALIDATE=1;;
t) TEST=1;;
r) REPORT=1;;
s) SYNC=1;;
c) CLEAR=1;;
?) print_help; exit 2;;
esac
done
echo "OPTIND: $OPTIND"
echo ${#@}
shift $((OPTIND - 1))
while (( "$#" )); do
if [[ $1 == -* ]] ; then
echo "All opts up front, please." >&2 ; print_help ; exit 2
fi
echo $1
shift
done
由于每个都是布尔标志选项,你不需要(事实上,不要)参数,所以我们摆脱了冒号。这些字符都不在IFS中,所以我们不需要将它包装在引号中,无论如何它都是getopts的一个标记。
接下来,我们将\?
更改为单?
并删除*
,因为*
在文字\?
之前匹配,我们也可以将规则组合成一个默认匹配。这是一件好事,因为使用-
前缀指定的任何选项都应该是一个选项,如果用户指定了您不期望的选项,用户将希望该程序失败。
getopts
将解析第一个不是参数的东西,并将OPTIND
设置为该位置的值。在这种情况下,我们将OPTIND - 1
(因为opts为0索引)从前面移开。然后,我们将通过将它们移开来回绕它们,回显它们或者如果它们以-
开头则失败。
并测试:
[getopts]$ ./go
OPTIND: 1
0
[getopts]$ ./go -t -v go go
OPTIND: 3
4
go
go
[getopts]$ ./go -d -v go go
./go: illegal option -- d
Usage
[getopts]$ ./go -t go -v go -d
OPTIND: 2
5
go
All opts up front, please.
Usage
答案 1 :(得分:2)
尝试以下解决方法:
# Parse the arguments.
while getopts ':h?f:' opts; do
case ${opts} in
f) # Foo argument.
;;
# My other arguments.
\? | h | *) # Prints help.
grep " .)\ #" $0
exit 0
;;
esac
done
所以基本上-?
/ -h
会根据自己的来源打印带有注释的参数。在选项之前指定:
也会打印任何其他未知参数的帮助。
答案 2 :(得分:1)
v:t:r:s:c:
应该是双引号
"v:t:r:s:c:"
根据您发布的脚本,您可能不需要所有这些冒号:
此外,您不需要*)
答案 3 :(得分:1)
如果要使?
与无效选项:vtrsc
匹配,则需要在getopts选项字符串中提供前导冒号。此外,您不需要在?