我有这个代码 -
#getoptDemo.sh
usage()
{
echo "usage: <command> options:<w|l|h>"
}
while getopts wlh: option
do
case $option in
(w)
name='1';;
(l)
name='2';;
(h)
name='3';;
(*)
usage
exit;;
esac
done
print 'hi'$name
当我运行bash getoptDemos.sh
(没有选项)时,它会打印hi
而不是调用 function usage
。当给出除 w、h 和 l 之外的选项时,它调用 use。那么当没有指定选项时它就无法工作。
我尝试使用?
,代替\?
但我无法实现我想要的。我的意思是所有的都说它可以使用。:
*
docs
getopt
?
我究竟做错了什么?
答案1
getopts
依次处理选项。这就是它的工作。如果用户碰巧没有传递任何选项,则第一次调用将getopts
退出 while 循环。
如果没有一个选项带参数,则 的值OPTIND
指示传递了多少个选项。一般来说,OPTIND
是选项或选项参数的参数数量,而不是非选项参数(操作数)。
while getopts …; do …; done
if [ $OPTIND -eq 1 ]; then echo "No options were passed"; fi
shift $((OPTIND-1))
echo "$# non-option arguments"
无论如何,您并不是试图确定是否没有选项,而是确定是否没有name
传递任何 -setting 选项。所以检查是否name
未设置(并注意先取消设置)。
答案2
当您在没有任何选项的情况下运行此脚本时,getopt 将返回 false,因此它根本不会进入循环。它只会下降到打印 - 这是 ksh/zsh 吗?
如果您必须有一个选项,那么最好的选择是在循环后测试 $name 。
if [ -z "$name" ]
then
usage
exit
fi
但在调用之前请确保$name
为空(因为shell 在启动时收到的环境中getopts
可能存在一个)$name
unset name
(getopts
循环之前)
答案3
我会用一个变量来检查它。如果 getopts 在没有参数的情况下永远不会通过循环,您可以使用它,例如如下所示:
#getoptDemo.sh
usage()
{
echo "usage: <command> options:<w|l|h>"
}
no_args="true"
while getopts wlh: option
do
case $option in
(w)
name='1';;
(l)
name='2';;
(h)
name='3';;
(*)
usage
exit;;
esac
no_args="false"
done
[[ "$no_args" == "true" ]] && { usage; exit 1; }
print 'hi'$name
答案4
在getopts
块之前,检查$1
(在命令行上传递的第一个参数/选项)是否等于空字符串。如果是,则打印使用消息并退出(或者如果您是无政府主义者,则执行一些“无选项”功能),否则让我们getopts
像平常一样解析选项。
getopts 中不包含此功能的原因是您已经可以在 bash 中使用“if-else”来完成它。例子:
if [[ $1 == "" ]]; then
Your_Usage_Function;
exit;
else
#parse options with getopts code block here;
fi
合理?