标准UNIX命一般都提供大量的选项和参数,例如:
ps --help
Usage:
ps [options]
Try 'ps --help <simple|list|output|threads|misc|all>'
or 'ps --help <s|l|o|t|m|a>'
for additional help text.
在这些工具的命令行处理中使用了C函数getopt;
shell脚本可以通过使用getopts来保持与UNIX一致的风格。
常用shell参数变量
- $0 :即命令本身,相当于C/C++中的argv[0]
- $1 :第一个参数.
- $2, $3, $4 … :第2、3、4个参数,依次类推。
- $# 参数的个数,不包括命令本身
- $@ :参数本身的列表,也不包括命令本身
- $* :和$@相同,但”$*“ 和 “$@”(加引号)并不同,”$*“将所有的参数解释成一个字符串,而”$@”是一个参数数组。
getopts
getopts有两个参数,
第一个参数是一个字符串,包括字符和“:”,每一个字符都是一个有效的选项,
如果字符后面带有“:”,表示这个字符有自己的参数。
如果字符串最前面带有“:”,表示开启静默模式,屏蔽系统提示错误。
getopts从命令中获取这些参数,并且删去了“-”,
并将其赋值在第二个参数中,如果带有自己参数,这个参数赋值在“OPTARG”中。
在使用getopts命令的时候,shell会自动产生两个变量OPTIND和OPTARG。
OPTIND初始值为1,其含义是下一个待处理的参数的索引。
只要存在,getopts命令返回true,所以一般getopts命令使用while循环;
OPTARG是当getopts获取到其期望的参数后存入的位置。
脚本
[ $# -eq 0 ] && usage
# option_string以冒号开头表示屏蔽脚本的系统提示错误,自己处理错误提示。
# 后面接合法的单字母选项,选项后若有冒号,则表示该选项必须接具体的参数
while getopts :s:t:i:oh OPTION
do
case $OPTION in
s)
STRING=$OPTARG
;;
t)
STRING=`cat $OPTARG`
;;
i)
IN=$OPTARG #$OPTARG为特殊变量,表示选项的具体参数
;;
o)
OUT=$OPTARG #$OPTARG为特殊变量,表示选项的具体参数
;;
h)
echo "\033[31mHelp Info:\033[0m"
java -jar sfntly-builds/java-openjdk-8/sfnttool/sfnttool.jar -h
exit 1
;;
\?) #如果出现错误,则解析为?
usage
;;
esac
done
#$OPTIND表示第几个选项,初始值为1
#shift $(($OPTIND - 1))
#if [ $# -eq 0 ]; then
# usage
#fi
shift
使用shift $(($OPTIND-1))的作用是:
通过shift $(($OPTIND - 1))的处理,$*中就只保留了除去选项内容的参数,可以在其后进行正常的shell编程处理,例如:
./xx -i in -o out para1 para2 ...
经过处理之后,$*为 para1 para2,方便后续脚本处理
while getopts s:h OPTION
do
case $OPTION in
s)
STRING=$OPTARG
;;
h)
echo "\033[31mHelp Info:\033[0m"
exit 1
;;
\?) #如果出现错误,则解析为?
usage
;;
esac
done
echo "OPTIND:"$OPTIND
shift $(($OPTIND - 1)) #除了选项之外,该脚本必须接至少一个参数
echo $0
echo $*
echo $@
if [ $# -eq 0 ]; then
usage
fi
for file in $@ #依次处理剩余的参数
do
echo $file
done
执行结果如下:
➜ /data/OpenSourceCode/subset-ttf > ./test.sh -s "123" test1 test2 test3
OPTIND:3
./test.sh $0
test1 test2 test3 $*
test1 test2 test3 $@
test1 file
test2
test3