Bash getopts将选项视为前一个选项的参数

Bash getopts将选项视为前一个选项的参数,bash,getopts,Bash,Getopts,我有以下脚本: #!/bin/bash USER="NONE" LOST=0 AVG=0 while getopts ":pmu:" OPTION; do case $OPTION in u) USER=$OPTARG ;; p) LOST=1 ;; m) AVG=1 ;; \?

我有以下脚本:

#!/bin/bash

USER="NONE"
LOST=0
AVG=0

while getopts ":pmu:" OPTION; do
    case $OPTION in
        u)
            USER=$OPTARG
            ;;
        p)
            LOST=1
            ;;
        m)
            AVG=1
            ;;
        \?)
            echo "Invalid argument: -$OPTARG"
            exit 1
            ;;
        :)
            echo "-$OPTARG requires an argument."
            exit 1
            ;;
    esac
done

echo "$USER-$LOST-$AVG"

exit 0
我希望
-u
选项接受一个参数。当在没有参数的情况下调用
-u
时,脚本会正确识别无效选项。但不幸的是,当我打字时:

myscript-u-m-p

它打印:

-m-1-0

因此,它使用
-m
作为
-u
参数,并忽略
-m
选项本身。

您说过
-u
选项后面跟着一个选项参数
-m
是一个字符串值;它以
-
符号开头这一事实对其作为选项参数的状态无关紧要;允许在选项参数值的开头使用
-

所以,你的观察是正确的。这是预期的设计;这就是函数的工作方式,它是POSIX的一个实现——事实上,这是这些准则的一个稍微放松的版本。如果您不喜欢它,请使用除
getopts
之外的其他方法,但您将与系统发生冲突

请注意,尽管POSIX
getopt()
在理论上允许“可选选项参数”,但在实践中,只有命令行上的最后一个选项可以有可选选项参数,这使得它们基本上没有用处

完全有可能设计出行为不同、基本上满足实用语法指南的选项解析系统;很多人都做过。事实上,GNU程序是一个扩展的实现,这很可能是您应该看到的——但它有一个非常不同的调用来实现行为(另请参见)。这两个系统都是不同的,要简洁而明确地描述所需的选项处理行为通常很复杂。有关更多信息,请参阅*


*谷歌搜索词“solaris clip”可以为电影“solaris”获取电影剪辑。一个有效的搜索术语是“Solaris命令行界面范例”。

因此,只有当
-u
始终用作最后一个参数时,
getopts
才可能对我有所帮助?我不会这样解释它。如果在命令行上有一个
-u
选项,则表示后面必须跟一个option参数。如果您希望
-u
可选地后跟一个option参数,那么
getopts
实际上不是要使用的工具;它不支持可选选项参数。您可能应该看看GNU
getopt
,我的答案更新中提到了这一点。