这是获取和设置OPTS的正确方法吗?
我希望能够接受很多选择,比如
/runthis.sh--option1 setuff--option2 setmorestuff
while :
do
case $1 in
-h | --help | -?)
usage
exit 0
;;
-o | --option1)
O=$2
shift 2
;;
-z | --option2)
Z=$2
shift 2
;;
--) # End of all options
shift
break
;;
-*)
echo "WARN: Unknown option (ignored): $1" >&2
shift
;;
*) # no more options. Stop while loop
break
;;
esac
done
如果您想解析选项,有两个选项可供选择:
- getopts(您可以查找getopts教程)
- 手动解析(我将在这里介绍)
使用getopts可能更容易,但没有那么灵活。您的代码基本上是正确的,但不适合更通用的选项解析。
- 正如chepner所说,
while true
与while :
相同。前者是首选,因为它能立即直观地了解自己在做什么。这是bash,而不是perl。不需要不必要的混淆 while true
不是解析选项的良好循环终止条件。如果你仔细想想,它告诉你循环在做什么。我必须一直到你的最后一个案例来了解发生了什么。正确的循环终止条件是当你用完命令行参数时- 我们的循环正在进行任何形式的统一循环,这一点并不明显。我必须阅读每一个案例,看看你在移动位置参数数组。由于您将在每次迭代中至少执行一个
shift
,所以请这样做 -
连接到#2,使用
*)
检查循环终止不是一个好主意。空字符串将匹配:/foo.sh--选项1"--选项2 123
正如您所看到的,
option2
永远不会使用您的代码获得它的值。幸运的是,#2也能解决这个问题。 - 最后一点:您可能应该引用所有变量,除非您确信它们不会包含空格。bash中的空格分割发生在变量替换之后,所以空格真的会把你搞砸。如果你不确定,引用它
您代码的修订版本可能是:
while [ $# -gt 0 ]
do
case "$1" in
-h | --help | -?)
usage
exit 0
;;
-o | --option1)
O="$2"
shift
;;
-z | --option2)
Z="$2"
shift
;;
--) # End of all options
shift
break
;;
*)
echo "WARN: Unknown option (ignored): $1" >&2
break
;;
esac
shift
done