通过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提供了两个变量
OPTARG
和OPTIND
。OPTARG
用来取当前选项的值,OPTIND
代表当前选项在参数列表中的位移。
下面看一个简单的例子:1234567891011121314151617echo "OPTIND starts at $OPTIND"while getopts "ab:" optnamedo case "$optname" in "a") echo "Option $optname is specified" ;; "b") echo "Option $optname has value $OPTARG" ;; "?") echo "Unknown option $OPTARG" ;; esacecho "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处理参数虽然是方便,但仍然有几个小小的局限:
- 选项参数的格式必须是-d val,而不能是中间没有空格的-dval。
- 所有选项参数必须写在其它参数的前面,因为getopts是从命令行前面开始处理,遇到非“-”开头的参数,或者选项参数结束标记“–”就中止了,如果中间遇到非选项的命令行参数,后面的选项参数就都取不到了。
- 不支持长选项,也就是–debug之类的选项。