Shell编程之条件语句


前言

在shell脚本程序中,各条语句将按先后顺序依次执行,从而实现批量处理的自动化过程。通过正确使用if语句,进行条件测试操作,使Shell脚本具有一定的“判断”能力,以根据不同的条件来完成不同的管理任务。从而减轻了管理员本身的负担,提升工作效率。


一、条件测试操作

1.test命令

  • 测试表达式是否成立,若成立返回0,否则返回其他数值
  • 格式:
格式一:test 条件表达式
格式二:[ 条件表达式 ]     //中括号和表达式中间至少应有一个空格[[ 条件表达式 ]]

2.文件测试

要使 Shell脚本程序具备一定的"智能",面临的第一个问题就是如何区分不同的情况以确定执行何种操作。例如,当磁盘使用率超过95%时,发送告警信息;当备份目录不存在时,能够自动创建;当源码编译程序时,若配置失败则不再继续安装等shell环境根据命令执行后的返回状态值 $? 来判断是否执行成功,当返回值为 0 时表示成功,否则(非0值)表示失败或异常。使用专门的测试工具——test 命令,可以对特定条件进行测试,并根据返回值来判断条件是否成立(返回值为0表示条件成立)。

  • 语法格式
[ 操作符 文件或目录 ]
  • 常用的测试操作符
-d:测试是否为目录(Directory)
-e:测试目录或文件是否存在(Exist)
-f:测试是否为文件(File)
-r:测试当前用户是否有权限读取(Read)
-w:测试当前用户是否有权限写入(Write)
-x:测试当前用户是否有权限执行(eXcute)
-b:测试是否为设备文件
-c:测试是否为字符设备文件
-s:测试存在且文件大小为空
-L:测试是否为链接文件

执行条件测试操作以后,通过预定义变量 $ ? 可以获得测试命令的返回状态值,从而判断该条件是否成立。

  • 例如,执行以下操作可测试目录/media/是否存在,如果返回值 $? 为 0,表示存在此目录,否则表示不存在或者虽然存在但不是目录
[root@c7-1 home]# test -d /etc/sysconfig/ && echo "是目录"  //如果前面的命令成功了,则运行后面的命令,返回结果 是目录;&&是而且的意思
是目录
[root@c7-1 home]# echo $?
0
#存在此目录

[root@c7-1 home]# [ -d /home/dashiji/ ]  
[root@c7-1 home]# echo $?
1
#目录不存在

[root@c7-1 home]# useradd dashiji
[root@c7-1 home]# [ -d /home/dashiji/ ] && echo "YES"  
YES
[root@c7-1 home]# echo $?
0

3.利用条件判断,创建文件

[root@c7-1 home]# ls /opt      //查看opt下没有dashiji文件
rh
[root@c7-1 home]# [ ! -e /opt/dashiji ] && mkdir /opt/dashiji
#感叹号取反 -e 测试目录或文件是否存在 ,若不存在 则创建

[root@c7-1 home]# echo $?
0
[root@c7-1 home]# ls /opt/   
dashiji  rh
#再次查看opt下已经有了dashiji

4.整数值比较

  • 格式:
[ 整数1 操作符 整数2 ]

整数值比较指的是根据给定的两个整数值,判断第一个数与第二个数的关系,如是否大于、等于、小于第二个数。整数值比较的常用操作选项如下,使用时将操作选项放在要比较的两个整数之间。

4.1 常用的测试操作符

-eq:第一个数等于(Equal)第二个数。
-ne:第一个数不等于(Not Equal)第二个数。
-gt:第一个数大于( Greater Than)第二个数。
-lt:第一个数小于(Lesser Than)第二个数。
-le:第一个数小于或等于(Lesser or Equal)第二个数。
-ge:第一个数大于或等于(Greater or Equal)第二个数

4.2 例:

[root@c7-1 home]# who | wc -l   //统计几个远程终端
3
[root@c7-1 home]# [ $(who | wc -l ) -le 5 ] && echo "用户太少"
用户太少
#判断远程终端是否小于等于五,若小于等于,则再运行后面的命令,echo "用户太少"

[root@c7-1 home]# [ $(who | wc -l ) -ge 2 ] && echo "用户太多"
用户太多

[root@c7-1 home]# Freec=$(free -m | grep "Mem:" | awk '{print $6}')
#定义变量Freec,检索Men,并打印其中第六列
[root@c7-1 home]# [ $Freec -lt 1024 ] && echo ${Freec}MB
416MB
#判断Freec是否小于1024,若小于;则运行 echo ${Freec}MB 

5.字符串比较

格式一:
[ 字符串1 = 字符串2 ]
[ 字符串1 != 字符串2 ]

格式二:
[ -z 字符串 ]

5.1 常用的测试操作符

=      	:字符串内容相同;第一个字符串与第二个字符串相同。
!=		:第一个字符串与第二个字符串不相同,!号表示相反的意思
-z 		:检查字符串是否为空(Zero),对于未定义或赋予空值的变量将视为空串。

5.2 例

[root@c7-1 ~]# echo $LANG
zh_CN.UTF-8
[root@c7-1 ~]# [ $LANG != "en.US" ] && echo "not en.US"
not en.US
#测试语言环境,判断是否为英文,LANG等不等于en.US,若不等于,执行后面的命令 not en.US

[root@c7-1 ~]# read -p "yes/no: " ACK
yes/no: ^C
[root@c7-1 ~]# [ -z $ACK ] && echo "你的变量是空字符" 
你的变量是空字符

6.逻辑测试

逻辑测试指的是判断两个或多个条件之间的依赖关系。当系统任务取决于多个不同的条件时,根据这些条件是否同时成立或者只要有其中一个成立等情况,需要有一个测试的过程。

格式1[ 表达式1 ] 操作符 [ 表达式2 ]

格式2:
命令1 操作符 命令2

6.1 常用的测试操作符

-a 或 && 	:逻辑与,“而且”的意思,只有当前后两个条件都成立时,整个测试命令的返回值﹐才为0(结果成立)。使用test命令测试时, && 可改为 -a
-o 或 || 	:逻辑或,“或者”的意思,只要前后两个条件中有一个成立,整个测试命令的返回值即为0(结果成立)。使用test命令测试时, || 可改为 -o
!			:逻辑否,表示"不",只有当指定的条件不成立时,整个测试命令的返回值才为0(结果成立)。

6.2 例

[root@c7-1 ~]# [ -d /etc ] && [ -r /etc ] && echo "you can open it"
you can open it
#只有前后两个条件都成立,才能返回0

[root@c7-1 ~]# [ -d /etc/ ] || [ -d /opt/ ] && echo ok
ok
#有一个条件成立即可


[root@c7-1 ~]# Munm=$(uname -r | awk -F. '{print $1}')
[root@c7-1 ~]# echo $Munm 
3
[root@c7-1 ~]# Snum=$(uname -r | awk -F. '{print $2}')
[root@c7-1 ~]# echo $Snum 
10
[root@c7-1 ~]# [ $Munm -ge 3 ] && [ $Snum -ge 6 ] && echo true
true
#查看当前Linux系统的内核版本是否大于3.4

二、if语句的结构

1.单分支结构

格式:
if 条件测试操作
then 命令序列
fi

在这里插入图片描述

1.1 例

[root@c7-1 ~]# vim test1.sh

#!/bin/bash					//固定格式
if ls /opt > /dev/dull		//if条件测试判断,查看是否有opt目录,并把输出信息给黑洞
then						//条件成立
        echo "it is ok"		//则echo一个it is ok
fi							//fi 结束判断

[root@c7-1 ~]# chmod +x test1.sh  //给权限
[root@c7-1 ~]# ./test1.sh 			//执行
it is ok
[root@c7-1 ~]# vim test2.sh

#!/bin/bash
MOUNT_DIR="/mnt/centos7"				//定义变量
if [ ! -e $MOUNT_DIR ]					//if判断 是否/mnt/centos7 不存在 
then									//条件成立
        mkdir "/mnt/centos7"			//创建 /mnt/centos7 
        echo "$MOUNT_DIR 并不存在,现已创建"	//输出返回值
fi										//fi 结束判断

[root@c7-1 ~]# chmod +x test2.sh    	//给与权限
[root@c7-1 ~]# ./test2.sh 				//执行
/mnt/centos7 并不存在,现已创建
[root@c7-1 ~]# ls /mnt
centos7
[root@c7-1 ~]# vim test3.sh

#!/bin/bash
read -p "请输入文件名:" file

if [[ $file = *.sh ]]
then
        echo "这是一个shell脚本"
fi

[root@c7-1 ~]# ./test3.sh 
请输入文件名:test1.sh
这是一个shell脚本

2.双分支结构

格式:
if 条件测试操作
	then 命令序列1
	else 命令序列2
fi

在这里插入图片描述

2.1 例

[root@c7-1 ~]# vim test4.sh

#!/bin/bash

IP=192.168.3.101				//定义变量

ping -c 2 -i 0.2 -W 3 $IP &> /dev/null	//ping2次,输出给黑洞

if [ $? -eq 0 ];then			//判断$?是否等于0
        echo "$IP is up"		//条件成立输出 IP is up
else							//条件不成立
        echo "$IP is down"		//输出 IP is down
fi

[root@c7-1 ~]# ./test4.sh 
192.168.3.101 is up
[root@c7-1 ~]# ./test4.sh 
192.168.3.101 is down
[root@c7-1 ~]# vim test5.sh

#!/bin/bash
if [ $UID -eq 0 ];then
        echo "当前登陆用户是管理员root"
else
        echo "当前登陆用户不是管理员root"
fi
[root@c7-1 ~]# sh test5.sh 
当前登陆用户是管理员root

[root@c7-1 ~]# cp test5.sh /home/zhangsan/
[root@c7-1 ~]# cd /home/zhangsan/
[root@c7-1 zhangsan]# chmod +x test5.sh 
[root@c7-1 zhangsan]# su zhangsan
[zhangsan@c7-1 ~]$ ./test5.sh 
当前登陆用户不是管理员root

3.多分支结构

#格式:
if 条件测试操作1
	then 命令序列1
elif 条件测试操作2
	then 命令序列2
else
	命令序列3
fi

在这里插入图片描述

3.1 例

[root@c7-1 zhangsan]# vim test6.sh

#!/bin/bash
read -p "请输入您的分数(0-100)" GRADE

if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ]		//判断$GRADE 是否大于85小于100
then
        echo "$GRADE 分,优秀"   				//条件满足则输出,不满足则继续往下进行判断

elif [ $GRADE -ge 60 ] && [ $GRADE -le 84 ]   	//判断是否大于60小于84
then											
        echo "$GRADE 分,合格"					

elif [ $GRADE -ge 100 ]
then
        echo "请输入分数为0~100"
else											//以上条件都不成立
        echo "$GRADE 分,不合格"
fi

4.if嵌套

[root@c7-1 ~]# vim httpd.sh

#!/bin/bash
pgrep -l httpd			//查找httpd进程
if [ $? -ne 0 ]			//判断是否在运行
then					//条件成立则
        if [ "$(rpm -q httpd)"="未安装软件包 httpd" ]		//判断httpd是否安装
        then											//条件成立
                yum install -y httpd					//没安装则安装
                systemctl start httpd					//启动服务
                echo "httpd服务已安装启动"				//输出已启动
        else											//若以上条件不成立
                systemctl start httpd					//启动httpd
                echo "httpd服务已启动"					//输出服务已启动
        fi												//结束判断
else					//若以上条件都不成立	
        echo "httpd is running"		//则输出running
fi						//结束判断

[root@c7-1 ~]# vim user.sh

#!/bin/bash
read -p "请输入用户名:" user					//定义交互式变量
if grep $user /etc/passwd &>/dev/dull		//条件测试,判断是否有这个用户并输入给黑洞
then										//条件成立 则
        if [ -d /home/$user ]				//判断用户是否有家目录
        then								//若条件成立
                echo "该用户状态正常"			//输出状态正常
        else								//若以上条件都不成立
                read -p "该用户没有家目录,是否删除该用户,请输入[yes/no]:" ask	//定义交互式变量
                if [ $ask == yes ]			//判断输入的是不是yes
                then						//若条件成立
                        echo "正在删除用户。。。"		//输出
                        userdel $user &>/dev/null;sleep 2	//删除该用户并延迟两秒
                        echo "该用户已删除"			//输出

                elif [ $ask == no ]			//条件测试2,判断输入的是不是no
                then						//若条件成立
                        exit				//退出
                fi							//结束判断
        fi									//结束判断

else				//若以上条件都不成立
        echo "该用户不存在"	//输出一个该用户不存在
fi					//结束判断


三、case语句结构

1.case多分支结构

格式:
case 变量值 in
模式1)
	命令序列1
	;;
模式2)
	命令序列2
	;;

………

*)
	默认命令序列
esac

1.1 例

[root@c7-1 ~]# vim test7.sh

#!/bin/bash
case $1 in
start)
/usr/bin/systemctl $1 httpd
/usr/bin/ps aux | grep httpd
echo "httpd start"
;;

stop)
/usr/bin/systemctl $1 httpd
/usr/bin/ps aux | grep httpd
echo "httpd stop"
;;

restart)
echo "httpd stop......"
/usr/bin/ps aux | grep httpd
/usr/bin/systemctl $1 httpd
echo "httpd restart......"
/usr/bin/ps aux |grep httpd
;;

status)
/usr/bin/systemctl $1 httpd
;;
*)
echo "plases inpunt start|stop|restart|status"
esac


总结

  • 条件测试的语法
    -文件测试、整数值比较、字符串比较、逻辑测试
  • if条件语句的语法
    -单分支、双分支、多分支
  • case多分支语句的语法
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值