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

Alt*_*lta 0 bash getopts arguments

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
Run Code Online (Sandbox Code Playgroud)

ilk*_*chu 6

是否可以检测 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: $*"
Run Code Online (Sandbox Code Playgroud)

那会给例如

$ 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
Run Code Online (Sandbox Code Playgroud)

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

$ 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
Run Code Online (Sandbox Code Playgroud)

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

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


ibu*_*fen 5

循环后,getopts习惯做:

\n
shift "$((OPTIND - 1))"\n
Run Code Online (Sandbox Code Playgroud)\n

剩下的参数将是剩下的。(例如参见man getopts1POSIX 的 EXAMPLE\xc2\xb9 部分)。

\n

要点是,从描述来看

\n
\n

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

\n
\n
\n

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

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

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

\n
\n

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

\n