一、条件测试表达式
不管什么编程语言基本都会提供顺序,选择,循环这三种编程控制结构,而在shell中这三种编程控制结构分别对应如下:
顺序:Command
选择:If and Case
循环:For and While and Until
一个正确编写的Linux应用程序会告诉操作系统执行成功与否,它用什么方法告诉系统呢?那就是我们经常用到的exit状态,exit的状态数值的范围为0~255之间。“0”表示成功,其他数值都表示失败。exit状态有两个很重要的功能。第一个作用是检测和处理错误,第二个作用是可以执行True/False条件测试。
二、exit 语句
一个好的脚本编程者应该在脚本完成时设置exit状态,为了实现这个要求,就要使用exit命令。exit命令使脚本带着状态值立刻退出。例如:
exit 0 #退出脚本,状态值为0(成功)
exit 1 #退出脚本,状态值为1(失败)
True/False的条件测试经常是通过表达式和if一起配合实现的,而条件测试表达式有两种语法形式:
第一种:test expression
PS:test命令工作很简单,如果给定的表达式为true,test退出的状态值为0,否则退出的状态值为1。
第二种:[ expression ]
PS:要注意表达式位于中括号的中间,两边必须有空格。
三、条件测试方法
整数测试
1 2 3 4 5 6 7 |
[ $? -eq 0 ] -eq #测试两个整数是否相等;相逢为true,不等为false。 -ne #测试两个整数是否不等;不等为true,相等为false。 -gt #测试一个数是否大于另一个数;大于为true,否则为false。 -lt #测试一个数是否小于另一个数;小于为true,否则为false。 -ge #大于或等于。 -le #小于或等于。 |
字符测试
1 2 3 4 5 |
[ $? = 0 ] = #第一个字符与第二个字符串是否相同;相同为true,不同为false。 != #第一个字符与第二个字符串是否不相同;其中!符号表示取反;不相同为true,相同为false。 -z #检查字符串是否为空,对于未定义或赋予空值的变量将视为空串;为空则为真否则为假。 -n #测试当前字符串如果大于0则为真,否则为假,注意这里如果用-n测试变量的值是否为空时,变量必须加上引号。否则不管变量有没有值都会为真。 |
# -z使用案例
1 2 3 4 5 |
$ test="" $ [ -z "$test" ] && echo "True" || echo "False" True $ [ ! -z "$test" ] && echo "True" || echo "False" False |
# -n使用案例
1 2 3 4 5 |
$ test="" $ [ -n $test ] && echo "True" || echo "False" True $ [ -n "$test" ] && echo "True" || echo "False" False |
文件测试
1 2 3 4 5 6 7 8 |
[ -e /etc/passwd ] -e #测试文件是否存在,存在为真否则为假。 -f #测试文件是否为普通文件,是为真否则为假。 -d #测试指定路径是否为目录,是为真否则为假。 -s #如果文件存在且至少有一个字符则为真,没有字符则为假。 -r #测试当前用户对指定文件是否有读取权限。 -w #测试当前用户对指定文件是否有写入权限。 -x #测试当期用户对指定文件是否有执行权限。 |
逻辑表达式
1 2 |
-a #逻辑与,操作符两边均为真,结果为真,否则为假。 -o #逻辑或,操作符两边均为真,结果为真,否则为假。 |
取反
1 2 |
[ ! $? = 0 ] ! #对以上整数测试,字符测试,文件测试在表达式中都可以进行取反操作,如[ ! $? = 0 ],原意识$?等于0则为真,加上“!”后就表示$?不等于0则为真。 |
判断是否为数值或字符
在Shell编程中还会经常需要判断一个输入是否为数值或字符,但是遗憾的是Shell不支持正则表达式也没有这种判断的方式(Shell变量测试也可以做到),但是高兴的是可以在Shell中可以使用任意Linux命令。所以我们可以借助sed、awk、grep等程序来进行判断,如下:
1 2 3 4 5 6 7 8 9 |
# 变量赋值; $ NUM=1 # 把变量的值通过管道传给sed做处理,sed就是把数值都替换为空,如果变量的值是数值,那么变量test的值就会为空; $ test=$(echo $NUM | sed 's/[0-9]//g') # 再使用字符测试条件(-z)测试变量test是否为空即可; $ echo $test $ [ -z $test ] && echo "digit" |
四、if 选择语句
if单分支语句语法:条件为真时执行;条件为假时不做任何事情
1 2 3 |
if condition; then statement1 fi |
IF双分支语句语法:条件为真时执行statement1;为假时执行statement2
1 2 3 4 5 |
if condition; then statement1 else statement2 fi |
IF多分支语句语法:条件为condition1时执行statement1;为condition2时执行statement2;否则执行statement3
1 2 3 4 5 6 7 |
if condition1; then statement1 elif condition2; then statement2 else statement3 fi |
五、case 选择语句
1 2 3 4 5 6 7 8 |
case VAR_NAME in ) statement1;; ) statement2;; ) statement3 esac |
六、实例
01)脚本判断条件之:以命令的状态返回结果为标准,测试redis用户是否存在
1 2 3 4 5 6 7 8 |
#!/bin/bash # NAME="redis" if id $NAME; then echo "user exist" else echo "user not exist" fi |
或
1 2 3 4 5 6 7 8 9 |
#! /bin/bash # NAME="redis" id $NAME if [ $? = 0 ]; then echo "user exist" else echo "user not exist" fi |
02)脚本判断条件之:以命令的执行结果为标准,测试用户的类型
1 2 3 4 5 6 7 8 |
#!/bin/bash # NAME="redis" if `id -u $NAME` -eq 0; then echo "This is a ADMIN" else echo "This is a common USER" fi |
03)脚本编写之:使用exit退出状态码(0正确状态;1-255错误状态),测试用户是否存在和用户UID和GID是否相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/bash # NAME="redis" id $NAME &> /dev/null if [ ! $? = 0 ]; then echo "NOT such user" exit 1 fi U=`id -u $USER` G=`id -g $USER` if [ $U -eq $G ]; then echo "UID is $U" echo "GID is $G" echo "UID = GID" else echo "UID is $U" echo "GID is $G" echo "UID != GID" fi |
04)脚本编写之:使用read -p接收用户输入做分数评级,用来测试多分支语句
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#!/bin/bash # read -p "Input your score(0-100):" score if [ $score -gt 100 ]; then echo "Your input $score is invalid." exit 1 fi if [ $score -ge 85 ] && [ $score -le 100 ]; then echo -e "\033[5;32m$score\033[0m,your score is very good." elif [ $score -ge 70 ] && [ $score -le 84 ]; then echo -e "\033[5;32m$score\033[0m,your score is good." else echo -e "\033[5;32m$score\033[0m,your score is bad." Fi |
05)脚本编写之:引用位置变量,判断用户随机输入的文件是否存在
1 2 3 4 5 6 7 8 9 |
#!/bin/bash # if [ -e $1 ]; then echo "File existed" else echo "File not existed" fi [root@localhost ~]# bash test.sh /etc/passwd #脚本中的$1就是引用用户输入的参数/etc/passwd |
06)脚本编写之:引用位置变量,判断用户是否输入了参数
1 2 3 4 5 6 7 8 9 10 |
#!/bin/bash # if [ $# -lt 1 ]; then echo "Usage: bash $0 FILE1…FILE2…" exit 1 if [ -e $1 ]; then echo "File existed" else echo "File not existed" fi |
1 |
[root@localhost ~]# bash test1.sh /etc |
# 脚本中$#显示输入参数的个数,如果小于1就会退出。
07)脚本编写之:使用case语句来判断输入的字符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/bin/bash # if [ $# -ge 1 ]; then case $1 in [0-9]) echo "This is a digit $1." ;; [a-z]) echo "This is a lower $1." ;; [A-Z]) echo "This is a upper $1." ;; *) echo "This is a special character $1." esac else echo "Usage: ./`basename $0` 1aA@.." fi |
08)脚本编写之:使用case语句来编写SysV风格的服务脚本
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#!/bin/bash # if [ $# -ge 1 ]; then case $1 in start) echo "It's starting." ;; stop) echo "It's stopping." ;; restart) echo "It's restarting" ;; reload) echo "It's reloading" ;; *) echo "Usage: ./$0 start|stop|restart|reload" esac else echo "Usage: ./`basename $0` start|stop|restart|reload" fi |
PS:这里只是给了一些最简单的小脚本,当有基础之后就可以写出一些比较大一点实用一点的小程序,前提是必须熟练看看前两张关于Shell的一些零散功能,就是把各个小的功能组合起来来完成一个大的功能,这就是Linux系统的特点。