如何检测 getopts 没有传递任何选项?

如何检测 getopts 没有传递任何选项?

我有这个代码 -

#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。那么当没有指定选项时它就无法工作。

我尝试使用?,代替\?但我无法实现我想要的。我的意思是所有的都说它可以使用。:*docsgetopt?

我究竟做错了什么?

答案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

合理?

相关内容