shell --选项详解
getopts从命令中获取这些参数,并且删去了“-”,并将其赋值在第二个参数中,如果带有自己参数,这个参数赋值在“optarg”中。提供getopts的shell内置了optarg这个变变,getopts修改了这个变量。
这儿是强调参数和选项的顺序,如果乱了顺序就完蛋了。
但是选项的顺序是可以颠倒的。
例子来源:
https://www.linuxidc.com/Linux/2018-07/153121.htm
https://www.cnblogs.com/yinghao1991/p/7123550.html
https://www.cnblogs.com/yaoyaojcy/p/9227272.html
getopts 不会重排所有参数的顺序,getopt 会重排参数顺序
https://www.cnblogs.com/qingergege/p/5914218.html
两个冒号表示该选项有一个可选参数,可选参数必须紧贴选项,如-carg 而不能是-c arg
注意:
--表示后面的是参数
getopt有时分不清什么是选项, 什么是参数, 最好在参数前面添加一个 --
getopt会对参数进行排序。
其他的博客中的 --long 不知道怎么使用,反正通不过。
http://blog.itpub.net/23655288/viewspace-735049/
一、找出选项
1、处理简单选项 在抽取每个参数是,使用case语句判断参数是否符合选项格式
[[email protected] ~]# cat t3.sh
#!/bin/bash
while [ -n "$1" ] ---此处的$1必须加且只能用双引号
do
case $1 in ---此处的$1可以加双引号或不加
-a) echo "found the -a option";; ---此处的两个分号一定要加上
-b) echo "found the -b option";;
-c) echo "found the -c option";;
*) echo "$1 is not an option";;
esac
shift
done
[[email protected] ~]# ./t3.sh -a -b -c -g
found the -a option
found the -b option
found the -c option
-g is not an option
case语句检查每个参数是否为有效的选项,当找到一个选项时,就在case语句中运行适当的命令。
2、从参数中分离选项
linux使用特殊字符码将选项和普通参数分开,这个字符码告诉脚本选项结束和普通参数开始的位置。所以发现双破折号后,
脚本就能够安全的将剩余的命令行参数作为参数而不是选项来处理。
[[email protected] ~]# cat t4.sh
#!/bin/bash
while [ -n "$1" ]
do
case $1 in
-a) echo "found the -a option";;
-b) echo "found the -b option";;
-c) echo "found the -c option";;
--) shift
break ;;
*) echo "$1 is not an option";;
esac
shift
done
count=1
for param in [email protected]
do
echo "parameter #count:$param"
count=$[ $count + 1 ]
done
[[email protected] ~]# ./t4.sh
[[email protected] ~]# ./t4.sh -a -v -b -- test1 test2 test3 ---当脚本到达双破折号是,停止处理选项,并将其余的参数视为命令行参数
found the -a option
-v is not an option
found the -b option
parameter #count:test1
parameter #count:test2
parameter #count:test3
3、处理带值的选项
[[email protected] ~]# cat t5.sh
#!/bin/bash
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 1;;
-c) echo "found the -c option";;
--) shift
break;;
esac
shift
done
count=1
for param in "[email protected]"
do
echo "parameter #count:$param"
count=$[ $count + 1 ]
done
[[email protected] ~]# ./t5.sh -a -b 56 -c -- test1 test2 test3
found the -a option
found the -b option,with parameter value 56
found the -c option
parameter #count:test1
parameter #count:test2
parameter #count:test3
本例中-b有附加的参数值,由于要处理的参数是$1.所以知道附加参数位于$2,于是从变量$2中抽取参数值。
二、getopt命令
getopt命令是个不错的工具,在处理命令行选项时非常的方便,它对命令行参数进行重新的组织,使其更便于在脚本中解析。
1、命令格式
getopt options optstring parameters
其中optstring是处理的关键,他定义命令行中有效的选项字母,然后,在每个需要参数值的选项字母后面放置一个冒号。
[[email protected] ~]# getopt ab:cd -a -b test1 -cd test2 test3
-a -b test1 -c -d -- test2 test3
如果指定的选项不包含在选项字符串内,getopt命令会默认生成一个错误信息
[[email protected] ~]# getopt ab:cd -a -b test1 -cde test2 test3
getopt:无效选项 -- e
-a -b test1 -c -d -- test2 test3
如果希望忽略这个错误消息,可以再命令中使用-q选项:
[[email protected] ~]# getopt -q ab:cd -a -b test1 -cde test2 test3
-a -b 'test1' -c -d -- 'test2' 'test3'
2、在脚本中使用getopt
使用set命令可以讲命令行参数变量替换为set命令的的命令行中的值。
set -- `getopt -q ab:cd "[email protected]"`
[[email protected] ~]# cat t7.sh
#!/bin/bash
set -- `getopt -q ab:c "[email protected]"`
while [ -n "$1" ]
do
case $1 in
-a) echo "found the -a option";;
-b) param="$2"
echo "found -b option with parameter value $param"
shift;;
-c) echo "found the -c option";;
--) shift
break;;
*) echo "$1 is not an option";;
esac
shift
done
count=1
for param in "[email protected]"
do
echo "parameter #$count:$param"
count=$[ $count + 1 ]
done
[[email protected] ~]# ./t7.sh -ac
found the -a option
found the -c option
[[email protected] ~]# ./t7.sh -a -b zhou -cd test1 test2 test3
found the -a option
found -b option with parameter value 'zhou'
found the -c option
parameter #1:'test1'
parameter #2:'test2'
parameter #3:'test3'
如果命令行参数中存在空格就会出现下面的情况
[[email protected] ~]# ./t7.sh -a -b zhou -cd "test1 test2" test3
found the -a option
found -b option with parameter value 'zhou'
found the -c option
parameter #1:'test1
parameter #2:test2'
parameter #3:'test3'
getopt命令不能很好的处理带空格的参数值,它将空格解析为参数分隔符,而不是将双引号引起来的两个值合并为一个参数。
解决上面的问题可以使用getopts命令。