通过getopts处理bash命令行参数

目录

作者:杨冬 欢迎转载,也请保留这段声明。谢谢!
出处:https://andyyoung01.github.io/http://andyyoung01.16mb.com/

如果要编写较复杂的带有较多命令行参数选项的bash脚本,通过bash内置的getopts命令进行处理较为方便。通过其与while循环配合,可以处理以“-”指定的参数。

在编写bash脚本时,经常需要获取到脚本后面的参数。bash提供了几个变量来表示位置参数,如下:

  • $# :代表后接的参数『个数』;
  • $@ :代表『 “$1” “$2” “$3” “$4” 』之意,每个变量是独立的(用双引号括起来);
  • $* :代表『 “$1c$2c$3c$4” 』,其中 c 为分隔字节,默认为空白键。

如果脚本后面参数选项较复杂时,单单使用上述变量并不十分方便,于是通过while循环与getopts及其提供的OPTARG与OPTIND变量相配合,可以十分方便得处理命令行参数。其一般的形式类似于如下:

getopts options variable
  • 其中,options为命令行参数列表,每个字母代表一个选项,字母后面如果带“:”意味着选项除了定义本身之外,还会带上一个参数作为选项的值。如果命令行中包含了没有在getopts列表中的选项,会有警告信息,如果在整个options字符串最前面也加上个“:”,就能消除警告信息了。
  • variable是当命令行参数是参数列表中的字母时,getopts将匹配的命令行参数字母保存在variable变量中,并且返回命令执行成功的状态值(就是0值)。如果命令行参数与参数列表中的字母不匹配,getopts将保存一个“?”到variable变量中,也返回一个命令执行成功的状态值。
  • 另外,getopts提供了两个变量OPTARGOPTINDOPTARG用来取当前选项的值,OPTIND代表当前选项在参数列表中的位移。

下面看一个简单的例子:

getopts.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/bin/bash
echo "OPTIND starts at $OPTIND"
while getopts "ab:" optname
do
case "$optname" in
"a")
echo "Option $optname is specified"
;;
"b")
echo "Option $optname has value $OPTARG"
;;
"?")
echo "Unknown option $OPTARG"
;;
esac
echo "OPTIND is now $OPTIND"
done

下面通过不同的命令行选项调用该脚本:

[yangdong@centos7-A ~]$ ./getopts.sh 
OPTIND starts at 1
[yangdong@centos7-A ~]$ ./getopts.sh -a
OPTIND starts at 1
Option a is specified
OPTIND is now 2
[yangdong@centos7-A ~]$ ./getopts.sh -b
OPTIND starts at 1
./getopts.sh: 选项需要一个参数 -- b
Unknown option 
OPTIND is now 2
[yangdong@centos7-A ~]$ ./getopts.sh -b optb
OPTIND starts at 1
Option b has value optb
OPTIND is now 3
[yangdong@centos7-A ~]$ ./getopts.sh -b optb -a
OPTIND starts at 1
Option b has value optb
OPTIND is now 3
Option a is specified
OPTIND is now 4
[yangdong@centos7-A ~]$ ./getopts.sh -c
OPTIND starts at 1
./getopts.sh: 非法选项 -- c
Unknown option 
OPTIND is now 2
[yangdong@centos7-A ~]$ ./getopts.sh -ab optab
OPTIND starts at 1
Option a is specified
OPTIND is now 1
Option b has value optab
OPTIND is now 3

使用getopts处理参数虽然是方便,但仍然有几个小小的局限:

  1. 选项参数的格式必须是-d val,而不能是中间没有空格的-dval。
  2. 所有选项参数必须写在其它参数的前面,因为getopts是从命令行前面开始处理,遇到非“-”开头的参数,或者选项参数结束标记“–”就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了。
  3. 不支持长选项,也就是–debug之类的选项。