1 找出选项
1.1 处理简单选项
主要可以通过shfit工具对获取的到$1变量对比程序允许的变量值判断;
1.2 从参数中分离选项
一般参数可能在后面跟上适当的参数值,例如 sed -f script data
所有如何把选项的参数与选项有效的分隔开也是一种很重要的技能,我们可以限制命令后面的规定格式,虽然没有很大的灵活性,但是它却解决了我们的问题,在linux当中用(--)这个特殊字符来表示选项的结束,参数项开始
下面进阶一点,讨论一下如何获取带值的选项
1.3 处理带值的选项
这个步骤主要是让我们脚本能够处理形如:./test -a test1 -b -c -d test2
这就得要求脚本呢必须能够检测命令行选项合适需要附加参数,并能够进行处理,下面的例子可以很好展示如何解决这类问题;
2 使用命令
getopt命令可以接受任意形式的命令行参数,在处理命令行选项和参数时非常方便
命令格式: getopt options optstring parameters
其中选项字符串是处理的关键,它定义命令行中有效选项字母,它还定义哪些选项字母需要参数值
首先,在选项字符串中列出将在脚本中用到的每个命令行选项字母。然后,在每个需要参数值的选项字母后面放置一个冒号。getopt命令根据定义的选项字符串解析提供的参数
请看下面的getopt示例:
$ getopt ab:cd -a -b test1 -cd test2 test3
-a -b test1 -c -d -- test2 test3
$
可见经过getopt的处理得到了规整的参数列表,注意它自动的把-cd 分为-c ,-d ,并插入破折号来分隔行中额外的参数
如果提供的参数不在optstring当中,getopt会给予提示出错信息
jiangjian@jiangjian-K42JZ:~/sh$ getopt ab:cd -a -b test1 -e -cd test2 test3
getopt:无效选项 -- e
-a -b test1 -c -d -- test2 test3
jiangjian@jiangjian-K42JZ:~/sh$
如果希望忽略这个错误信息,可以在命令中使用-q选项
jiangjian@jiangjian-K42JZ:~/sh$ getopt -q ab:cd -a -b test1 -e -cd test2 test3
-a -b 'test1' -c -d -- 'test2' 'test3'
jiangjian@jiangjian-K42JZ:~/sh$
现在介绍如何在脚本中使用getopt
这里存在一个技巧
set命令的一个选项是双破折号,表示将命令行参数变量替换为set命令的命令行中的值
set -- `getopt -q ab:cd "$@"`
按照上面的技巧我们试着编写一个:
jiangjian@jiangjian-K42JZ:~/sh$ cat test60.sh
#!/bin/bash
set -- `getopt -q ab:c "$@"`
while [ -n "$1" ]
do
case "$1" in
-a) echo "Found the -a option";;
-b) param="$2"
echo "Found the -b option with parameter value $param"
shift ;;
-c) echo "Found the -c option";;
--) shift
break;;
*) echo "$1 is not option "
esac
shift
done
count=1
for param in "$@"
do
echo "Parameter #$count:$param"
count=$[$count + 1]
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test60.sh -a -b test10 -c -d 1 2 3
Found the -a option
Found the -b option with parameter value 'test10'
Found the -c option
Parameter #1:'1'
Parameter #2:'2'
Parameter #3:'3'
jiangjian@jiangjian-K42JZ:~/sh$
getopts命令
不同于getopt,getopts每次获取参数列表当中的一个合法项,当处理完最后的即返回一个大于0 的退出状态
格式:getopts optstring variable
optstring和getopt大致相同,主要区别在与禁止输出错误信息,这里直接在optstring前面加一个冒号:
其中每次返回的值存放在variable当中,可以用于for循环当中迭代,getopts当中使用两个环境变量,环境变量OPTARG中包含需要参数值选项要使用的值,环境变量OPTIND 包含的值表示getopts停止处理时在参数列表中的位置,这样,处理完选项后可以继续处理其他命令行参数。
jiangjian@jiangjian-K42JZ:~/sh$ cat test61.sh
#!/bin/bash
while getopts :ab:c opt
do
case "$opt" in
a) echo "Found -a option";;
b) echo "Found -b option,with value $OPTARG";;
c) echo "Found -c option";;
*) echo "$opt is unknown option";;
esac
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test61.sh -a -b test1 -c
Found -a option
Found -b option,with value test1
Found -c option
jiangjian@jiangjian-K42JZ:~/sh$
必须注意上面的case选项中不在包括(-)
getopts会自动处理未定义的参数
jiangjian@jiangjian-K42JZ:~/sh$ ./test61.sh -a -b test1 -c -d
Found -a option
Found -b option,with value test1
Found -c option
? is unknown option
jiangjian@jiangjian-K42JZ:~/sh$
另外getopts知道合适停止处理选项,将参数选项交给您处理。getopts每个处理选项,环境变量OPTIND的值都会增加1,当达到getopts处理的末尾时,可以使用shift命令和OPTIND值进行操作来移动到参数;
实例如下:
jiangjian@jiangjian-K42JZ:~/sh$ cat test62.sh
#!/bin/bash
while getopts :ab:cd opt
do
case "$opt" in
a) echo "Found the -a option";;
b) echo "Found the -b option,with vale $OPTARG";;
c) echo "Found the -c option";;
d)echo "Found the -d option";;
*)echo "$1 is not an option";;
esac
done
shift $[$OPTIND - 1]
count=1
for parameter in $@
do
echo "Patameter #$count:$parameter"
count=$[$count + 1]
done
jiangjian@jiangjian-K42JZ:~/sh$ ./test62.sh -a -b test1 -c -d 1 2 3 4
Found the -a option
Found the -b option,with vale test1
Found the -c option
Found the -d option
Patameter #1:1
Patameter #2:2
Patameter #3:3
Patameter #4:4
jiangjian@jiangjian-K42JZ:~/sh$