linux shell 左移,linux shell--getopts

在写sh脚本的时候,常常需要运行时输入一些数据。基本的$*,执行的情况,大概就是$0 $1 $2 $3…… 那么,那些系统命令里的参数又是怎么做出来的呢?我们自己的脚本如何搞出来$0-$1的效果呢?这就是getopts的作用了。举例如下:

#!/bin/bash

echo "OPTIND starts at $OPTIND"

while getopts ":pq:" optname

do

case "$optname" in

"p")

echo "Option $optname is specified"

;;

"q")

echo "Option $optname has value $OPTARG"

;;

"?")

echo "Unknown option $OPTARG"

;;

":")

echo "No argument value for option $OPTARG"

;;

*)

# Should not occur

echo "Unknown error while processing options"

;;

esac

echo "OPTIND is now $OPTIND"

done

在使用getopts命令的时候,shell会自动产生两个变量OPTIND和OPTARG。

OPTIND初始值为1,其含义是下一个待处理的参数的索引。只要存在,getopts命令返回true,所以一般getopts命令使用while循环;

OPTARG是当getopts获取到其期望的参数后存入的位置。而如果不在其期望内,则$optname被设为?并将该意外值存入OPTARG;

如果$optname需要拥有具体设置值而实际却没有,则$optname被设为:并将丢失设置值的optname存入OPTARG;对于$optname,可以用后标:来表示是否需要值;而前标:则表示是否开启静默模式。

================================================================

获取类型的选项:

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

command -options parameters

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

getopts option_string variable

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

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

optstring  option字符串,会逐个匹配

varname每次匹配成功的选项

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

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

$OPTARG特殊变量,option argument,不同情况下有不同的值

细则1:

当optstring以”:“开头时,getopts会区分invalid option错误和miss option argument。 invalid option错误时,varname会被设成?,$OPTARG是出问题的option;miss 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为空)

1 #!/bin/bash

2 if [[ $# -lt 1 ]];then

3     echo "USAGE:`basename $0` [-a] [-b value] [-c]"

4     exit 1

5 fi

6

7 while getopts :ab:c name

8 do

9     case $name in

10         a)  aflag=1

11         echo "a"

12         ;;

13         b)  bflag=1

14

15         if [[ ${OPTARG:0:1} = "-" ]]; then

16             echo "invalid parameter of $OPTARG"

17             exit 1

18         fi

19

20         bval=$OPTARG

21         ;;

22         c)  cflag=1

23         echo "c"

24         ;;

25         \?) echo "Invalid option :`basename $0` [-a] [-b value] [-c]"

26         exit 1

27         ;;

28         :) echo "$0:Must supply an argument to -$OPTARG."

29         exit 1

30         ;;

31     esac

32 done

33 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个参数

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

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

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

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

你可能感兴趣的:(linux,shell,左移)