本文共 5224 字,大约阅读时间需要 17 分钟。
getopts可以编写脚本,使控制多个命令行参数更加容易。getopts用于形成命令行处理标 准形式。原则上讲,脚本应具有确认带有多个选项的命令文件标准格式的能力。
2.1 getopts脚本实例 通过例子可以更好地理解getopts。以下getopts脚本接受下列选项或参数。 • a 设置变量ALL为true • h 设置变量HELP为true
• f 设置变量FILE为true • v 设置变量VERBOSE为true
对于所有变量设置,一般总假定其初始状态为false:
[sam@chenwy sam]$ ./getopt1 -a -h ALL is true HELP is true [sam@chenwy sam]$ cat getopt1 #!/bin/sh ALL=false HELP=false FILE=false VERBOSE=false
while getopts ahfgv OPTION do case $OPTION in a)ALL=true echo "ALL is $ALL" ;; h)HELP=true echo "HELP is $HELP" ;; f)FILE=true echo "FILE is $FILE" ;; v)VERBOSE=true echo "VERBOSE is $VERBOSE" ;; esac done
getopts一般格式为: getopts option_string variable 在上述例子中使用脚本: while getopts ahfgv OPTION 可以看出while循环用于读取命令行,options_string为指定的5个选项(-a,-h,-f,-g,-v),脚本中varible为OPTION。注意这里并没有用连字符指定每一单个选项。 运行上述脚本,给出几个有效和无效的选项,结果为:
[sam@chenwy sam]$ ./getopt1 -a -h ALL is true HELP is true [sam@chenwy sam]$ ./getopt1 -a -h -p ALL is true HELP is true ./getopt1: illegal option -- p [sam@chenwy sam]$ ./getopt1 -p ./getopt1: illegal option -- p
可以看出不同选项的结合方式。
2.2 getopts使用方式 getopts读取option_string,获知脚本中使用了有效选项。 getopts查看所有以连字符开头的参数,将其视为选项,如果输入选项,将把这与option_string对比,如果匹配发现,变量设置为OPTION,如果未发现匹配字符,变量能够设置为?。重复此处理过程直到选项输入完毕。 getopts接收完所有参数后,返回非零状态,意即参数传递成功,变量OPTION保存最后处理参数,一会儿就可以看出处理过程中这样做的好处。
2.3 使用getopts指定变量取值 有时有必要在脚本中指定命令行选项取值。getopts为此提供了一种方式,即在option_string中将一个冒号放在选项后。例如: getopts ahfvc: OPTION 上面一行脚本指出,选项a、h、f、v可以不加实际值进行传递,而选项c必须取值。使用选项取值时,必须使用变量OPTARG保存该值。如果试图不取值传递此选项,会返回一个错误信息。错误信息提示并不明确,因此可以用自己的反馈信息屏蔽它,方法如下: 将冒号放在option_string开始部分。 while getopts :ahfgvc: OPTION 在case语句里使用?创建一可用语句捕获错误。
[sam@chenwy sam]$ cat getopt1 #!/bin/sh ALL=false HELP=false FILE=false VERBOSE=false COPIES=0
while getopts :ahfgvc: OPTION do case $OPTION in a)ALL=true echo "ALL is $ALL" ;; h)HELP=true echo "HELP is $HELP" ;; f)FILE=true echo "FILE is $FILE" ;; v)VERBOSE=true echo "VERBOSE is $VERBOSE" ;;
c)COPIES=$OPTARG echo "COPIES is $COPIES" ;; ?) echo "`basename ` -[a h f v] -[c value] file" ;; esac done
输入所有合法选项:
[sam@chenwy sam]$ ./getopt1 -ah -c 3 ALL is true HELP is true COPIES is 3
选项- c不赋值,将返回错误,但显示的是脚本语句中的反馈信息 [sam@chenwy sam]$ ./getopt1 -ah -c ALL is true HELP is true getopt1 -[a h f v] -[c value] file
去掉前面的冒号,提到系统的提示消息
:[sam@chenwy sam]$ ./getopt1 -ah -c ALL is true HELP is true ./getopt1: option requires an argument -- c
2.4 访问取值方式 getopts的一种功能是运行后台脚本。这样可以使用户加入选项,指定不同的磁带设备以备份数据。使用getopts实现此任务的基本框架如下:
[sam@chenwy sam]$ cat backups #!/bin/sh OUITE=n DEVICE=awa LOGFILE=/tmp/logbackup usage() { echo "Usage: `basename ` -d [device] -l [logfile] -q" exit 1 } if [ $# = 0 ] then usage fi
while getopts :qd:l: OPTION do case $OPTION in q) QUIET=y LOGFILE="/tmp/backup.log" ;; d)DEVICE=$OPTION ;; l)LOGFILE=$OPTARG ;; ?)usage ;; esac done echo "you chlose the ..." echo "Quite=$QUIET $DEVICE $LOGFILE"
上述脚本中如果指定选项d,则需为其赋值。该值为磁带设备路径。用户也可以指定是否备份输出到登录文件中的内容。运行上述脚本,指定下列输入:
[sam@chenwy sam]$ ./backups -d /dev/rmt0 -q you chlose the ... Quite=y d /tmp/backup.log
getopts检查完之后,变量OPTARG取值可用来进行任何正常的处理过程。当然,如果输入选项,怎样进行进一步处理及使该选项有有效值,完全取决于用户。 以上是使用getopts对命令行参数处理的基本框架。 实际处理文件时,使用for循环,就像在tr-case脚本中使用shift命令过滤所有选项一样。 使用getopts与使用shift方法比较起来,会减少大量的编程工作。
2.5 使用getopts处理文件转换 现在用所学知识将tr-case脚本转换为getopts版本。命令行选项getopts方法与shift方法的唯一区别是一个VERBOSE选项。 变量VERBOSE缺省取值为no,但选择了命令行选项后,case语句将捕获它,并将其设为yes,反馈的命令是一个简单的if语句。
if [ "VERBOSE" = "on" ];
thenecho "doing upp on $LOOP ..newfile called $LOOP$EXT" fi
如果正在使用其他系统命令包,它总是反馈用户动作,只需简单地将包含错误的输出重定向到/dev/null中即可。如: 命令>/dev/null 2 >&1 缺省时VERBOSE关闭(即不显示),使用- v选项可将其打开。例如要用VERBOSE将myfile文件系列转换为小写,方法如下: tr-case -l -v myfile1 myfile2 ... 或者 tr-case -v -l myfile1 myfile2 ... 可能首先注意的是使用g e t o p t s后脚本的缩减效果。这里用于文件处理的脚本与s h i f t版本相同。 脚本如下:
[sam@chenwy sam]$ cat tr_case1 #!/bin/sh FILES="" TRCASE="" EXT="" OPT=no VERBOSE="off"
while getopts :luv OPTION do case $OPTION in l)TRCASE="lower" EXT=".LC" OPT=yes ;; u)TRCASE="upper" EXT=".UC" OPT=yes ;; v)VERBOSE=on ;; ?)echo "usage: `basename `: -[l|u] -v file[s]" exit 1 ;; esac done
shift `expr $OPTIND - 1` if [ "$#" = "0" ] || [ "$OPT" = "no" ] then echo "usage: `basename `: -[l|u] -v file[s]" exit 1 fi
for LOOP in "$@" do if [ ! -f $LOOP ] then echo "`basename ` :error cannot find file $LOOP" exit 1 fi echo $TRCASE $LOOP case $TRCASE in lower) if [ "VERBOSE" = "on" ];then echo "doing...lower on $LOOP..newfile" fi cat $LOOP|tr "[a-z]" "[A-Z]" > $LOOP$EXT ;; upper) if [ "VERBOSE" = "on" ];then echo "doing upper on $LOOP..newfile" fi cat $LOOP|tr "[A-Z]" "[a-z]" >$LOOP$EXT ;;
esac done
在脚本中指定命令行选项时,最好使其命名规则与U N I X或L I N U X一致。下面是一些选项及其含义的列表。
选项含义 - a 扩展 - c 计数、拷贝 - d 目录、设备 - e 执行 - f 文件名、强制 - h 帮助 - i 忽略状态 - l 注册文件 - o 完整输出 - q 退出 - p 路径 - v 显示方式或版本
3 小结 正确控制命令行选项会使脚本更加专业化,对于用户来说会使之看起来像一个系统命令。 本章讲到了控制命令行选项的两种方法,shift和getopts。使用getopts检测脚本的数量远远小于使用s h i f t方法检测脚本的数量。 shift也克服了脚本参数$ 1 . . $ 9的限制。使用shift命令,脚本可以很容易偏移至所有调用参数,因此脚本可以做进一步处理。
上一篇:
下一篇:
转载地址:http://mdmti.baihongyu.com/