我正在学习getopt
命令并使用以下诊断脚本来研究它的工作原理:
$ 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
-->--
-->c
5
现在,getopt
在c
之后添加$5
作为--
的值。这不是一个选项,c
在这里意味着什么?
getopt
指定有效选项的参数中定义,为什么程序不会引发错误?我已经浏览了getopt
man page以及some tutorials,但无法做出明确的解释。
答案 0 :(得分:1)
通常,直到全部都不会生成非选项参数输出 选项及其参数已生成。那么' - '是 生成为单个参数,之后是非选项 参数的顺序,每个参数都作为一个单独的参数。
即。生成--
本身以表示选项的结束。 (之后,如果存在位置参数,则会生成位置参数。)
我想这是为了统一 - 使用相同的代码逻辑,无论用户是否在命令行上指定了--
。
在第二种情况下,c
是位置参数。 getopt
不会以任何方式检查位置参数,而是按原样传递。该联机帮助页没有说明验证非选项参数:
getopt 用于在命令行中分解(解析)选项以方便 通过shell程序解析,并检查合法选项。
最后,请注意要正确处理带有空格的参数,您需要:使用$@
代替$*
;引用; eval
与set
;并根据Example of how to parse options with bash/getopt使用getopt
的增强模式。还应该使用bash
-e
模式退出无效选项上的程序:
#!/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
因为它:使得获取下一个参数变得容易 - 获取选项& #39; s参数并检查是否有参数,如果它是可选的;完成选项后,检查剩余(位置)参数的数量。
答案 1 :(得分:0)
我通常使用这样的结构来运行getopts:
# 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} }。例如,如果上面的代码段是名为$1
的脚本的一部分,则可能会运行:
foo
将$ foo -ab meh smoo blarg
设置为$opt_a
,将1
设置为$opt_b
,将"meh"
设置为$1
,将"smoo"
设置为{{ 1}}用于代码段后面的脚本部分。