getopts和getopt
这两个命令都是linux shell中解析命令行参数的命令。getopt是属于util-linux包的一部分。用man getopt可以查看到相关帮助。在我的电脑(Ubuntu 16.04)上man getopts是没有的。这两个命令相比较getopt要比getopts复杂些,且getopts不支持长选项。
getopts
先贴一段示例Shell代码:
while getopts :ab:c: opt; do
case $opt in
a)
echo "option:a, arg:"$OPTARG", index:"$OPTIND;;
b)
echo "option:b, arg:"$OPTARG", index:"$OPTIND;;
c)
echo "option:c, arg:"$OPTARG", index:"$OPTIND;;
*)
echo "Error option, index:"$OPTIND;;
esac
done
echo "End";
shell的输出结果:
hostname@hostname ~/W/t/tmp> sh ./opts.sh -a -b banana -s -ccherry
option:a, arg:, index:2
option:b, arg:banana, index:4
Error option, index:5
option:c, arg:cherry, index:6
End
hostname@hostname ~/W/t/tmp>
getops用while循环加case进行逐个解析参数。其中ab:c:为有效的单字符选项,a即代表选项-a。后面不带冒号:表示该选项无参数。带冒号即表示有参数,b:即代表-b banana,参数banana是一定要给出的。另外最开始的冒号:表示使用的是Slient模式,如果给出无效的选项,不会输出Illegal option -。
另外该有几个参数变量。OPTARG中存储的该选项的参数,如果没有参数即为空。OPTIND存储的当前参数的索引。此外如果选项无效的话,OPTARG会设为*,OPTIND为错误选项的索引。
getopt
同样先贴一段代码:
#!/bin/bash
TEMP=`getopt -o ab:e:: -l apple,banana: -n "opt-long.sh" -- "$@"`
eval set -- "$TEMP"
while true
do
case "$1" in
-a | --apple)
echo "option a"
shift;;
-b)
echo "option b arg $2"
shift 2;;
--banana)
echo "option banana arg $2"
shift 2;;
-e)
echo "option e arg $2"
shift 2;;
--)
shift
break;;
*)
echo "Internal error!"
exit 1;
esac
done
shell输出的结果如下:
deranpan@panderan ~/W/t/tmp> sh ./opt-long.sh -a -b b-arg -ee-arg --apple --banana banana
option a
option b arg b-arg
option e arg e-arg
option a
option banana arg banana
deranpan@panderan ~/W/t/tmp>
getopt选项-o后接单字符选项,格式同getopts。选项-l后接长选项用逗号,分隔。在单字符选项中如果一个选项后面跟着两个冒号::表示该选项是一个可带参数的选项,并且该参数必须紧跟在选项后。