bash shell笔记4 处理用户输入(2)

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循环。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/24605.html