我有一个具有这种用法的脚本:
myscript [options] positional-args... -- [fwd-params]
因为[options]
可以有长或短的变体,我喜欢使用getopt
.但我有麻烦了。
我getopt
这样使用:
args=$(getopt -o a:,b --long alpha:,gamma -- "$@")
eval set -- "$args"
while : ; do
case "$1" in
-a | --alpha) a="$2" ; shift 2 ;;
-b ) b=true ; shift ;;
--gamma ) g=true ; shift ;;
-- ) shift ; break ;;
esac
done
positionals=()
while [ $# -gt 0 ] ; do
case "$1" in
* ) positionals+=("$1"); shift ;;
-- ) shift ; break ;;
esac
done
# What-ever is left in "$@" needs to be forwarded to another program
backend "$@"
如果我没有的话,这非常有用[fwd-params]
:
$ getopt -o a:,b -- -a 1 -b pos1 pos2
-a '1' -b -- 'pos1' 'pos2'
^-- getopt adds this to help me find
the end-of-options/start-of-positionals
但如果用户定义了任何[fwd-params]
.这是我想要的输出:
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' '--' 'fwd1'
^
\- I'll use this to delimit
the positional arguments
from the forwarding ones.
这就是我实际得到的。用户的意图--
已经被过滤掉了。
$ getopt -o a:,b -- -a 1 -b pos1 pos2 -- fwd1
-a '1' -b -- 'pos1' 'pos2' 'fwd1'
将我的位置参数与转发的位置参数区分开来的最佳方法是什么?
好吧,如果用户传递参数
-a 1 -b pos1 pos2 -- fwd1
, getopt 会将 当作--
标记,使所有后续参数都成为非选项。这里这本身并不是一个立场争论。如果您希望
--
按原样显示,您的用户必须明确添加标记,然后再添加另一个标记--
来分隔两组位置,例如:或者,您可以在选项字符集前面加上 a
+
来询问 POSIX 行为,其中任何非选项都标记选项的结尾。这样,--
您的示例中的 就不再是标记,而是本身的位置:但请注意,如果第一组中没有位置参数,用户仍然需要手动添加总共两个
--
s:我可能会做类似于 GNU Parallel 所做的事情,并使用其他一些固定字符串来分隔两种类型的位置。例如,让脚本查找 a
::
,而保留--
getopt。因此用户将输入-a 1 -b pos1 pos2 :: fwd1
(带或不带--
):或者第一组中没有位置: