2、特殊的参数变量
在bash shell中有一些特殊的变量用户跟踪命令行参数。
2.1、参数计数
我们可以使用bash shell提供的特殊变量$#来检测执行脚本时所包含的命令行参数的个数,看如下例子:
[root@ ~]# cat 2.1test
#!/bin/bash
echo there were $# parameters supplied.
[root@ ~]# chmod u+x 2.1test
[root@ ~]# ./2.1test
there were 0 parameters supplied.
[root@ ~]# ./2.1test aa bb cc
there were 3 parameters supplied.
所以,$#是一个值得我们记住脑中的好变量!
2.2、获取所有参数
有时候需要获取命令行中的参数,并对它们进行迭代。这里主要通过两个变量来实现对命令行参数的迭代,分别是:
变量$*和变量$@
变量$*将所有参数视为一个单词
变量$@将分别对待每个参数
我们看个例子\(≧▽≦)/
[root@ ~]# chmod u+x 2.2test
[root@ ~]# cat 2.2test
#!/bin/bash
a=1
for param1 in "$*"
do
echo "\$* parameter #$a = $param1"
a=$[ $a+1 ]
done
b=1
for param2 in "$@"
do
echo "\$# parameter #$b = $param2"
b=$[ $b+1 ]
done
c=1
for param3 in "$#"
do
echo "the total counts = $param3"
c=$[ $c+1 ]
done
[root@ ~]# ./2.2test a b c d e f
$* parameter #1 = a b c d e f
$# parameter #1 = a
$# parameter #2 = b
$# parameter #3 = c
$# parameter #4 = d
$# parameter #5 = e
$# parameter #6 = f
the total counts = 6
通过一个for循环迭代特殊变量,充分体现出$*$@$#三个特殊变量用途!
3、移位
bash shell提供了一个工具叫shift命令,实现改变命令行参数的相对位置
默认将每个参数变量左移一位。即为,$3的值移动给变量$2($n+1->$n),而变量$1则被丢弃,当然,$0这个程序名称没变。下面看个例子:
[root@ ~]# cat 3test
#!/bin/bash
count=1
while [ -n "$1" ]
do
echo "parameter #$count = $1"
count=$[ $count + 1 ]
shift
done
[root@ ~]# chmod u+x 3test
[root@ ~]# ./3test linuxidc emc linux rac
parameter #1 = linuxidc
parameter #2 = emc
parameter #3 = linux
parameter #4 = rac
每测试一个参数,使用shift命令将参数移前一位,所以通过while循环即可是的每个参数都变成$1被循环下去显示出来。当然,我们可以指定shift的位数,而不是默认的一位。看如下例子:
[root@ ~]# cat 3test
#!/bin/bash
echo "the original parameter : $*"
shift 3
echo "the new shift parameter is : $1"
[root@ ~]# ./3test aa bb cc dd ee
the original parameter : aa bb cc dd ee
the new shift parameter is : dd
指定位数为3后,aa bb cc则被忽略了,直接把dd当成$1.
4、处理选项
选项是有破折号引导的单个字母,它更改命令的行为。如下罗列一些标准化选项:
**********************************************
选项 描述
-a 实现所有对象
-c 生成计数
-d 指定目录
-e 展开对象
-f 指定读取数据的文件
-h 显示命令的帮助信息
-i 忽略大小写
-l 生成长格式的输出
-n 使用非交互式(批量)模式
-o 指定一个输出文件来重定向输出
-q 以quite模式退出
-r 递归处理目录和文件
-s 以silent模式执行
-v 生成verbose模式
-x 排除和拒绝
-y 设置所有提问回答为yes
**********************************************
4.1、处理简单选项
先来看一个例子:
[root@ ~]# cat 4test
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "the -a option exists";;
-b) echo "the -b option exists";;
-c) echo "the -c option exists";;
*) echo "the '$1' is not an option ";;
esac
shift
done
[root@ ~]# ./4test -a -b -c -d -e
the -a option exists
the -b option exists
the -c option exists
the '-d' is not an option
the '-e' is not an option
通过case语句循环判断各个选项,并且通过shift灵活移动选项变量。
4.2、从参数中分离选项
执行shell脚本经常会遇到使用选项又需要使用参数的情况。在linux中的标准方式是通过特殊字符码(--,双破折号)将二者分开,表示说当这个脚本程序发现双破折号后,就自动把剩余的命令行视为参数,而不再是选项了,如下看个例子:
[root@ ~]# cat 4test
#!/bin/bash
while [ -n "$1" ]
do
case "$1" in
-a) echo "the -a option exists";;
-b) echo "the -b option exists";;
-c) echo "the -c option exists";;
--) shift
break;;
*) echo "the '$1' is not an option ";;
esac
shift
done
count=1
for param in $@
do
echo "parameter #$count:$param"
count=$[ $count + 1 ]
done
[root@ ~]# ./4test -a -c -f -- -b test
the -a option exists
the -c option exists
the '-f' is not an option
parameter #1:-b
parameter #2:test
如上先通过while循环,把满足条件的选项显示出来,不满足条件的选项也显示出,并说明 is not an option ,当使用--把剩下的被脚本识别为参数的命令行则通过break跳出循环,并且在shift作用下置位成$1,然后在for循环下逐一显示出来,表示现实出来的即为参数,而非选项!
如上的脚本得仔细分析,不然很容易出错。
如果不通过双破折号隔离,如下的结果也是我们想象之中的:
[root@ ~]# ./4test -a -c -f -b test
the -a option exists
the -c option exists
the '-f' is not an option
the -b option exists
the 'test' is not an option
完全是while循环的判断,没法跳出来执行for循环。