shell 脚本getopts用法总结

最近在写一个消费者的发布脚本,用到getopts,所以总结下getopts的用法

getopts是shell命令行参数解析工具,意在从shell 命令行当中解析参数。命令格式:

getopts optstring name [arg ...]

optstring列出了对应的shell 脚本可以识别的所有参数。比如:shell script可以识别-a, -f 以及-s参数,则optstring就是afs;如果对应的参数后面还跟随一个值,则在相应的optstring后面加冒号比如a:fs表示a参数后面会有一个值出现,-a value的形式另外,getopts执行匹配到a的时候,会把value存放在一个OPTARG的shell 变量中。如果optstring是以冒号开头的,命令行当中出现了optstring当中没有的参数将不会提示错误信息。

name表示的是参数的名称,每次执行getopts,会从命令行当中获取下一个参数,然后存放到name中。如果获取到参数不在optstring中,则name的值被设置为?。命令行当中的所有参数都有一个index,第一个参数从1开始,依次类推,另外有一个名为OPTIND的shell变量存放下一个要处理的参数的index。

直接上例子:

#!/bin/bash
 
func() {
    echo "Usage:"
    echo "test.sh [-j S_DIR] [-m D_DIR]"
    echo "Description:"
    echo "S_DIR,the path of source."
    echo "D_DIR,the path of destination."
    exit -1
}
 
upload="false"
 
while getopts 'h:j:m:u' OPT; do
    case $OPT in
        j) S_DIR="$OPTARG";;
        m) D_DIR="$OPTARG";;
        u) upload="true";;
        h) func;;
        ?) func;;
    esac
done
 
echo $S_DIR
echo $D_DIR
echo $upload

//执行结果:
[root@bobo tmp] sh test.sh -j /data/usw/web -m /opt/data/web
/data/usw/web
/opt/data/web
false
 
[root@bobo tmp] sh test.sh -j /data/usw/web -m /opt/data/web -u
/data/usw/web
/opt/data/web
true
 
[root@bobo tmp] sh test.sh -j /data/usw/web
/data/usw/web
 
false
 
[root@bobo tmp] sh test.sh -m /opt/data/web                 
 
/opt/data/web
false
 
[root@bobo tmp] sh test.sh -h
test.sh: option requires an argument -- h
Usage:
test.sh [-j S_DIR] [-m D_DIR]
Description:
S_DIR,the path of source.
D_DIR,the path of destination.
 
[root@bobo tmp] sh test.sh j
 
 
false
 
[root@bobo tmp] sh test.sh j m
 
 
false

getopts后面跟的字符串就是参数列表,每个字母代表一个选项,如果字母后面跟一个冒号,则表示这个选项还会有一个值,比如-j /data/usr/web 和 -m /opt/data/web。而getopts字符串中没有跟随冒号的字母就是开关型的选项,不需要指定值,等同于true/false,只要带上这个参数就是true。

shift位移使用举例:

#!/bin/bash
#test3.sh

func() {
        echo "Usage:"
        echo "test.sh [-j S_DIR] [-m D_DIR]"
        echo "Description:"
        echo "S_DIR, the path of source."
        echo "D_DIR, the path of destination."
        exit -1
}

upload="false"

echo $OPTIND

while getopts 'h:s:d:u' OPT; do
        case $OPT in
                s) S_DIR="$OPTARG";;
                d) D_DIR="$OPTARG";;
                u) upload="true";;
                h) func;;
                ?) func;;
        esac
done

echo $OPTIND
echo $(($OPTIND -))
echo $1

//执行结果:
[root@bobo tmp] sh test3.sh -s /data/usw/web beijing
1              #执行的是第一个"echo $OPTIND"
3              #执行的是第二个"echo $OPTIND"
beijing        #此时$1是"beijing"
 
[root@bobo tmp] sh test3.sh -s /opt/data/web beijing                
1              #执行的是第一个"echo $OPTIND"
3              #执行的是第二个"echo $OPTIND"
beijing
 
[root@bobo tmp] sh test3.sh -s /data/usw/web -d /opt/data/web beijing
1              #执行的是第一个"echo $OPTIND"
5              #执行的是第二个"echo $OPTIND"
beijing
 
                  参数位置: 1        2       3       4        5     6
[root@bobo tmp] sh test3.sh -s /data/usw/web -d /opt/data/web -u beijing
6
beijing