一个健壮的程序应该能够无序的处理用户的参数列表。

例如你要写个程序,它接受 -n-b 两个参数,那么用户在使用你的这个程序时既可能把 -n 参数作为第一个参数,也可能把 -b 作为第一个参数。所以在写程序时,应该尽量实现参数的无序化处理。

可以利用下面要介绍的 shiftgeopts 两个命令。

shift

功能: 将参数向左移动一个位置。通常在参数较少的程序中用来实现参数的无序处理。

用法

1
2
3
echo "Current command line args are: \$1=$1, \$2=$2, \$3=$3"
shift # 参数左移
echo "After shift command the args are: \$1=$1, \$2=$2, \$3=$3"

如果一开始的参数是: $1 = -f,$2 = foo,$3 = bar

那么经过左移后,参数变成: $1 = foo, $3 = bar

如果要移动两个位置,只需要执行 shift 2,以此类推。

示例

shift命令最大的用处在于当程序的参数较少时可以用来实现无序的参数列表。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
while [ "$1" ]
do
if [ "$1" = "-b" ]; then
ob="$2"
case $ob in
16) basesystem="Hex";;
8) basesystem="Oct";;
2) basesystem="bin";;
*) basesystem="Unknown";;
esac
shift 2
elif [ "$1" = "-n" ]
then
num="$2"
shift 2
else
echo "Program $0 does not recognize option $1"
exit 1
fi
done
output=`echo "obase=$ob;ibase=10; $num;" | bc`
echo "$num Decimal number = $output in $basesystem number system(base=$ob)"

getopts

上面的 shift 在参数较少的时候比较实用,但是如果参数比较多的时候,单纯使用 shift 的话,程序的逻辑就会变得非常复杂,而且效率也越来越低下。此时可以用 getopts 来实现一个逻辑更加清晰且高效的无序化方案。

功能: 检验命令行参数的有效性。通常用在循环体内。

用法

1
getopts {参数字符串} {变量 1}

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
#
# Usage: ani -n -a -s -w -d
#
#
# help_ani() To print help
#
help_ani()
{
echo "Usage: $0 -n -a -s -w -d"
echo "Options: These are optional argument"
echo " -n name of animal"
echo " -a age of animal"
echo " -s sex of animal "
echo " -w weight of animal"
echo " -d demo values (if any of the above options are used "
echo " their values are not taken)"
exit 1
}
#
#Start main procedure
#
#
#Set default value for variable
#
isdef=0
na=Moti
age="2 Months" # may be 60 days, as U like it!
sex=Male
weight=3Kg
#
#if no argument
#
if [ $# -lt 1 ]; then
help_ani
fi
while getopts n:a:s:w:d opt
do
case "$opt" in
n) na="$OPTARG";;
a) age="$OPTARG";;
s) sex="$OPTARG";;
w) weight="$OPTARG";;
d) isdef=1;;
\?) help_ani;;
esac
done
if [ $isdef -eq 0 ]
then
echo "Animal Name: $na, Age: $age, Sex: $sex, Weight: $weight (user define mode)"
else
na="Pluto Dog"
age=3
sex=Male
weight=20kg
echo "Animal Name: $na, Age: $age, Sex: $sex, Weight: $weight (demo mode)"
fi