首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Getopt生成一个双破折号(--),即使命令行中没有一个,也不验证无关的参数。

Getopt生成一个双破折号(--),即使命令行中没有一个,也不验证无关的参数。
EN

Stack Overflow用户
提问于 2018-06-18 09:42:55
回答 2查看 2.1K关注 0票数 0

我正在学习getopt命令,并使用以下诊断脚本来研究它的工作原理:

代码语言:javascript
复制
$ cat test-getopt.sh
#!/bin/bash
args=`getopt ab:c $*`
set -- $args
for i
do
    echo "-->$i"
done
echo $#

我无法理解它在以下情况下的表现。你能澄清一下吗?

  • 第一宗案件: $ ./test-getopt.sh -ab arg -c ->-a->-b->arg->-c->-5 为什么getopt要添加--作为$5?这里是什么意思?指出选择的终点?
  • 第二宗案件: $ ./test-getopt.sh -ab arg c-> -- a -b ->arg->->c5 现在,getopt添加了c作为$5的值,在--之后。这不是一种选择,c在这里意味着什么?
代码语言:javascript
复制
- Which kind of element is it -- option, or option's argument, or positional argument?
- It's not defined in `getopt`'s parameter specifying valid options, why doesn't the program raise an error?

我已经浏览了一下手册页一些 教程,但没能给出一个清晰的解释。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-06-18 10:36:16

根据命令页

通常,在生成所有选项及其参数之前,不会生成非选项参数输出。然后“--”作为一个参数生成,然后按照找到它们的顺序生成非选项参数,每个参数作为一个单独的参数。

也就是说,--本身就是用来表示选项的结束的。(在此之后,如果存在位置参数,则生成位置参数。)

我想这是为了一致性--使用相同的代码逻辑,而不管用户是否在命令行上指定了--

在第二种情况下,c是一个位置参数。位置参数不被getopt以任何方式检查,而是按原样传递。该手册没有提到验证非选项参数:

getopt用于在命令行中拆分(解析)选项,以便于shell过程进行解析,并检查合法选项。

最后,请注意,要正确处理带空格的参数,您需要:使用$@而不是$*;引用;evalset;以及使用getopt的增强模式--与如何使用bash/getopt解析选项的示例一样。还应该使用bash -e模式在无效选项下退出程序:

代码语言:javascript
复制
#!/bin/bash -e
args=`getopt -o ab:c -- "$@"`
eval set -- "$args"
for i
do
  echo "-->$i"
done
echo $#

$ ./test-getopt.sh -b "arg ument"
-->-b
-->arg ument
-->--
3

$ ./test-getopt.sh -d ; echo $?
getopt: unknown option -- d
1

此外,按照相同的示例使用带有while循环的shift可能比for更方便:使获取下一个参数变得更容易--获取选项的参数,并检查是否有参数是可选的;在使用选项时检查其余(位置)参数的数量。

票数 2
EN

Stack Overflow用户

发布于 2018-06-18 12:40:37

我通常使用这样的构造来运行getopts:

代码语言:javascript
复制
# Set defaults
opt_a=0; opt_b=""; opt_c=false

# Step through options
while getopts ab:c opt; do
        case "$opt" in
                a) opt_a=1 ;;
                b) opt_b="${OPTARG:?The -b option requires an argument.}" ;;
                c) opt_c=true ;;
                *) usage; exit 64 ;;
        esac
done
shift $((OPTIND - 1))

最后使用这样的shift会将位置参数移回原来的位置,这样,getopts 不能进程的第一个参数就变成了$1。例如,如果上面的片段是名为foo的脚本的一部分,则可以运行:

代码语言:javascript
复制
$ foo -ab meh smoo blarg

这将将$opt_a设置为1,将$opt_b设置为"meh",将$1设置为"smoo",将$2设置为"blarg",用于代码片段后面的脚本部分。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50906636

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档