getopts 和 getopt 用法简记

这两个命令都是linux shell中解析命令行参数的命令。getopt是属于util-linux包的一部分。用man getopt可以查看到相关帮助。在我的电脑(Ubuntu 16.04)上man getopts是没有的。这两个命令相比较getopt要比getopts复杂些,且getopts不支持长选项。

getopts

先贴一段示例Shell代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
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的输出结果:

1
2
3
4
5
6
7
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

同样先贴一段代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#!/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输出的结果如下:

1
2
3
4
5
6
7
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后接长选项用逗号,分隔。在单字符选项中如果一个选项后面跟着两个冒号::表示该选项是一个可带参数的选项,并且该参数必须紧跟在选项后。