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)
是否可以检测 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
采用选项参数。)
无论如何,除非您正在做的事情比通常需要的复杂得多,否则没有任何理由考虑--
. 即使您做了更复杂的事情,您也可能会考虑在外部(并使用另一个分隔符)进行操作,类似于如何给出getopts
in 表达式,或者 GNU Parallel 如何获取由 分隔的参数列表等。find
:::
::::
循环后,getopts
习惯做:
shift "$((OPTIND - 1))"\n
Run Code Online (Sandbox Code Playgroud)\n剩下的参数将是剩下的。(例如参见man getopts
1POSIX 的 EXAMPLE\xc2\xb9 部分)。
要点是,从描述来看:
\n\n\n以下任何一项都应标识选项的结尾:第一个“--”参数不是选项参数,找到不是选项参数并且不以“-”开头的参数,或者遇到一个错误。
\n
假设你有pattern ab:
,那么(这里是4.示范--
):
-a x y z
\n-a
旗帜。休息:x y z
-a -b foo x y z
\n-a
标志 +-b
值 = foo
. 休息:x y z
-b foo -a -b bar x y z
\n-a
标志 +-b
值 =foo
和bar
. 休息:x y z
-b
均已传递。取决于脚本如何处理。-a -b foo -- -a -b x y z
\n-a
标志 +-b
值 = foo
. 休息:-a -b x y z
-a -b foo -x y z
\n-x
-b foo bar -x y z
\n-b
值 = foo
. 休息:bar -x y z
-b -- -a bar -x y z
\n-a
标志 +-b
值 = --
. 休息:bar -x y z
至于 7,请注意,作为选项的参数可以有任何字符串,包括--
, 或""
。
$((...))
\xc2\xb9 但请注意该示例如何缺少;周围的引号。POSIX 示例确实假设$IFS
包含其默认值,这是不幸的,因为它们不能在任何上下文中使用。