Linux shell getopts 学习

获取UNIX类型的选项:linux

  unix有一个优势就是标准UNIX命令在执行时都具备相同的命令行格式:shell

  command -options parametersbash

  若是在执行Shell程序也采用上述格式,Bourne Shell中提供了一条获取和处理命令行选项的语句,即getopts语句。该语句的格式为:ide

  getopts option_string varname函数

  其中option_string中包含一个有效的单字符选项。若getopts命令在命令行中发现了连字符,那么它将用连字符后面的字符同 option_string相比较。如有匹配,则把变量varname的值设为该选项。若无匹配,则variable设为?。当getopts发现连字符后面没有字符,会返回一个非零的状态值。Shell程序中能够利用getopts的返回值创建一个循环。测试

  有时侯选项中还带一个值,getopts命令一样也支持这一功能。这时须要在option_string中选项字母后加一个冒号。当 getopts命令发现冒号后,会从命令行该选项后读取该值。若该值存在,那么将被存在一个特殊的变量OPTARG中。若是该值不存在,getopts命令将在OPTARG中存放一个问号,而且在标准错误输出上显示一条消息。spa

  optstring  option  字符串,会逐个匹配命令行

  varname     每次匹配成功的选项unix

  arg             参数列表,没写时它会取命令行参数列表字符串

  $OPTIND     特殊变量,option index,会逐个递增初始值为1

  $OPTARG    特殊变量,option argument,不一样状况下有不一样的值

 

细则1
optstring以":"开头时,getopts会区分invalid option错误和miss option argument invalid option错误时,varname会被设成?,$OPTARG是出问题的optionmiss option argument,varname会被设成:(在个人fedora系统里测试OPTARG?),$OPTARG是出问题的option.


optstring不以":"开头,invalid option错误和miss option argument错误都会使varname被设成?, $OPTARG是出问题的option(在个人fedora系统里测试OPTARG为空).

细则2
optstring中的字母跟”:“,代表该option可接参数,参数(argument)放在$OPTARG,若是缺参数,optstring是以”:“开头,varname的值会是:(在个人fedora系统里测试OPTARG?),$OPTARG是该option, 不然varname的值是?,$OPTARG是该option.(参照细则1)(在个人fedora系统里测试OPTARG为空) 

 

#!/bin/bash

if [[ $# -lt 1 ]];then 
    echo "USAGE:`basename $0` [-a] [-b value] [-c]" 
    exit 1 
fi  

while getopts :ab:c name 
do 
    case $name in 
         a)  aflag=1 
              echo "a" 
              ;; 
         b)  bflag=1 
             if [[ ${OPTARG:0:1} = "-" ]]; then 
                echo "invalid parameter of $OPTARG" 
                exit 1 
             fi 
             bval=$OPTARG 
             ;; 
          c)  cflag=1 
              echo "c" 
              ;; 
         \?) echo "Invalid option :`basename $0` [-a] [-b value] [-c]" 
             exit 1 
             ;; 
         :) echo "$0:Must supply an argument to -$OPTARG." 
            exit 1 
           ;; 
     esac

done

echo $bval

在getopts分析选项时,若是-b后面不带参数,直接跟-c的话,那么-c将做为-b的参数。

下面是一个简单例子(脚本为getopt):


#/bin/bash

echo $0
echo $*

while getopts ":a:bc" opt
do
        case $opt in
                a )
                        echo $OPTARG                   
                        echo $OPTIND;;
                b )
                        echo "b $OPTIND";;
                c )
                        echo "c $OPTIND";;
                ? )
                        echo "error"                   
                        exit 1;;
        esac

done

echo $OPTIND
echo $*

shift $(($OPTIND - 1))

echo $*
echo $0

 

运行sh getopt.sh  -a 12 -b -c 34 -m
输出:

getopt.sh
-a 12 -b -c 34
12
3
b 4
c 5
5
-a 12 -b -c 34
34
getopt.sh

 

能够得出一些结论: 

1$0在用sh 或者 ./执行脚本时,指的是脚本名,用source.执行时,永运是bash,这也反应了sh 或者 ./执行脚本的原理和source的方式是不一样的.

2$1 (1....n)指的第一个参数到....n个参数

3OPTARG存储相应选项的参数 OPTIND指向的是下一个参数的index

4shift 会改变参数的顺序,经过左移去掉某些参数

5getopts检测到非法参数就会中止,好比上例中遇到34就会终止,并不会去检测-m了,也就是说只要前一个参数是合法的(包含在option_string中的),就会继续检测下一个参数。

另外: unset OPTIND  能够解决shell脚本的函数中使用getopts  

相关文章
相关标签/搜索