检测 getopts `--` (双破折号)以发出消息

检测 getopts `--` (双破折号)以发出消息

getopts我正在使用通过名为 的变量使用的惯用方式arg。我可以捕获选项名称,如下所示。是否可以检测 getopts 到达“--”的时刻,以便我可以发出消息?

while getopts "$shortopts" arg; do
   echo "--> arg: $arg"
   case $arg in
   ("V")
     printf '%s\n' "Version" 
     return
     ;;
   ("u")
     printf '%s\n' "Usage" 
     return
     ;;
   ("h")
     printf '%s\n' "Help" 
     return
     ;;
   esac
done

答案1

是否可以检测 getopts 到达“--”的时刻,以便我可以发出消息?

你不应该需要这样做。

getopts实现标准选项处理,这意味着当它看到不是选项的参数时,或者如果它看到参数 时,它会停止寻找选项--,这会显式终止选项列表。 (第一点与 GNU 自定义不同,GNU 自定义在整个命令行上查找选项。)

程序不需要关心 meet --

也就是说,由于getopts不会丢弃位置参数列表,因此您可以查看其中最后一个参数是否为--.

#!/bin/bash
while getopts a:bc opt; do
    echo "option $opt arg $OPTARG"
done
last=
if [ "$OPTIND" -ge 2 ]; then
        shift "$((OPTIND - 2))"
        last=$1
        shift 1
else
        shift "$((OPTIND - 1))"
fi
if [ "$last" = "--" ]; then
        echo "options were terminated by a double-dash (or last arg was an option-argument '--')"
fi
echo "remaining args: $*"

那会给例如

$ bash opts.sh -a blah -- -b foo
option a arg blah
options were terminated by a double-dash (or last arg was an option-argument '--')
remaining args: -b foo

但由于它只查看最后一个参数,因此它可以是--分隔符,也可以--作为某个选项的选项参数。例如,这是误报,--这里不是分隔符:

$ bash opts.sh -a -- foo
option a arg --
options were terminated by a double-dash (or last arg was an option-argument '--')
remaining args: foo

当然,您也可以实现自己的选项处理,但是这样做有点烦人,因为 shell 使处理子字符串变得很困难。 (您需要将其识别-abc为三个不同的选项,或者一个或两个,具体取决于是否-a-b采用选项参数。)

无论如何,除非您正在做的事情比通常需要的复杂得多,否则没有任何理由考虑--.即使您做了更复杂的事情,您也可能会考虑在外部(并使用另一个分隔符)进行操作,类似于如何给出getoptsin 表达式,或者 GNU Parallel 如何获取由 分隔的参数列表等。find:::::::

答案2

循环后,getopts习惯做:

shift "$((OPTIND - 1))"

剩下的参数将是剩下的。 (参见man getopts1POSIX 的示例 1 部分)。

重点是,来自描述:

以下任何情况都应标识选项的结尾:第一个“--”参数不是选项参数,找到不是选项参数且不以“-”开头的参数,或者遇到错误。


假设你有pattern ab:,那么(这里是4.示范--):

  1. -a x y z
    • -a旗帜。休息:x y z
  2. -a -b foo x y z
    • -a标志 +-b值 = foo.休息:x y z
  3. -b foo -a -b bar x y z
    • -a标志 +-b值 =foobar.休息:x y z
    • 的两个值均已-b传递。取决于脚本如何处理。
  4. -a -b foo -- -a -b x y z
    • -a标志 +-b值 = foo.休息:-a -b x y z
  5. -a -b foo -x y z
    • 错误/未知选项-x
  6. -b foo bar -x y z
    • -b值 = foo.休息:bar -x y z
  7. -b -- -a bar -x y z
    • -a标志 +-b值 = --.休息:bar -x y z

至于 7,请注意,作为选项的参数可以有任何字符串,包括--, 或""


$((...))1 但请注意该示例如何缺少;周围的引号。 POSIX 示例确实假设$IFS包含其默认值,这是不幸的,因为它们不能在任何上下文中使用。

答案3

getopts循环条件设置为初始化为 0 的变量,在这种"--")情况下将其设置为 1。例如

stop=0
...
while [[ 0 -eq $stop ]] ; do
# getopts call ...
...
"--") stop=1;;r
esac
done

相关内容