shell脚本基础之条件语句详解

目录

一、条件语句

1、测试

1.1 测试判断

1.2 关系运算符(比较整数数值)

1.3 字符串比较

1.4 逻辑测试(短路运算)

1.5 双中括号的用法

1.6 () 与 {} 的用法及区别

1.7 括号组合使用的区别

2、if语句 

2.1 单分支if语句

2.2 双分支if语句

2.3 多分支if语句

2.4 shell脚本的if语句案例

案例一

案例二

案例三

案例四

案例五

案例六

 案例七

3、case语句

3.1 case语句格式

3.2 shell脚本的case语句案例

案例一

案例二

案例三

案例四

案例五


一、条件语句

条件语句用于根据给定条件执行不同的代码块

1、测试

1.1 测试判断

#测试判断
格式一: test  条件表达式
格式二: [条件表达式]

#文件测试
格式一: test   -操作符  条件表达式
格式二: [-操作符  目录或文件]
-操作符说明
-d测试是否为目录(Directory)
-e测试目录或文件是否存在(Exist)
-a测试目录或文件是否存在(Exist),有点小bug,不建议使用
-f测试是否为文件(File)
-r测试当前用户是否有权限读取(Read)
-w测试当前用户是否有权限写入(Write)
-x测试当前用户是否有权限执行(excute)
-L测试是否为软连接文件
-t fd文件描述符是否在某终端已经打开
-N FILE文件自从上一次被读取之后是否被修改过
-O FILE当前有效用户是否为文件属主
-G FILE当前有效用户是否为文件属组
-s FILE是否存在且非空

注:

判断该脚本是否有读取权限,是以实际效果为主而不是表面的显示,需要注意root权限

其他所有用户没有执行权限则root也没有执行权限,只要有一个用户有执行权限那么root用户也会拥有执行权限

注:

-e 选项和 -a 选项的区别:

-a选项在取反即使用 ! 有bug,所以不建议使用-a选项来检测文件或目录是否存在,建议用-e选项

1.2 关系运算符(比较整数数值)

[ 整数1   -操作符   整数2 ] 
关系运算符说明举例
-eq检测两个数是否相等,相等返回 true[ $a -eq $b ] 返回 false
-ne检测两个数是否不相等,不相等返回 true[ $a -ne $b ] 返回 true
-gt检测左边的数是否大于右边的,如果是返回 true[ $a -gt $b ] 返回 false
-lt检测左边的数是否小于右边的,如果是则返回 true[ $a -lt $b ] 返回 true
-ge检测左边的数是否大于等于右边的,如果是则返回 true[ $a -ge $b ] 返回 false
-le检测左边的数是否小于等于右边的,如果是则返回 true[ $a -le $b ] 返回 true

 

1.3 字符串比较

[ 整数1   -操作符   整数2 ] 
字符串比较运算符说明举例
=检测两个字符串是否相等,相等返回 true[ $a = $b ] 返回 false
!=检测两个字符串是否不相等,不相等返回 true[ $a != $b ] 返回 true
-z检测字符串长度是否为0,为0返回 true[ -z $a ] 返回 false
-n检测字符串长度是否不为 0,不为 0 返回 true[ -n "$a" ] 返回 true
$检测字符串是否不为空,不为空返回 true[ $a ] 返回 true

 

[ 字符串1 = 字符串2 ]       字符串1与字符串2是否相同

[ 字符串1 !=  字符串2 ]     字符串1与字符串2是否不相同

[ -z  字符串 ]              字符串是否为空

[ -n  字符串 ]              字符串是否存在

1.4 逻辑测试(短路运算)

格式1: [ 表达式1 ]  操作符  [ 表达式2 ]  ... 
格式2: 命令1  操作符  命令2  ... 
布尔运算符说明举例
!非运算,表达式为 true 则返回 false,否则返回 true[ ! false ] 返回 true
-o或运算,有一个表达式为 true 则返回 true[ $a -lt 20 -o $b -gt 100 ] 返回 true
-a与运算,两个表达式都为 true 才返回 true[ $a -lt 20 -a $b -gt 100 ] 返回 false
逻辑操作符说明
&&逻辑与,“而且”的意思全真才为真,一假即假
 ||逻辑或,“或者”的意思一真即为真,一真即真
&&与||结合使用,一般只有以下一种用法

cmd1  &&  cmd2  ||  cmd3

该语句会有两种输出情况:
①cmd1的条件如果为真,就会执行cmd2的条件,那么整个式子一定为真,就不需要执行cmd3的条件
②cmd1的条件如果为假,就不需要执行cmd2的条件,因为这时(cmd1 && cmd2)整个为假,那么则需要执行cmd3的条件

案例一: 

使用ping命令检测主机网络联通性

#!/bin/bash
ping -c2 $1 &>/dev/null && echo "$1 is online" || echo "$1 is offline"
#使用ping命令检测主机的联通性,如果能ping通则返回"&1 is online",不能ping通则返回"$1 is offline"

亦可以用if语句实现

#!/bin/bash
ping -c2 -W2 172.16.12.10
if
        [ $? = 0 ]
then
        echo "该主机网络通顺"
        exit 1
fi
        echo "该主机网络不通"

案例二:

#!/bin/bash
use=`df|tr -s " "|grep sda|cut -d " " -f5|tr -d %`

[ $use -ge 80 ] && echo "磁盘使用量过高" | mail -s warning 3487547879@qq.com || echo "磁盘剩余量足够"
#当磁盘使用量超过80%时,会发送邮件到QQ邮箱警示你,当磁盘使用量小于80%,执行脚本会回复你“磁盘剩余量足够”

1.5 双中括号的用法

双中括号 [[ ... ]] 通常用于条件测试和比较操作。它们提供了更多的功能和灵活性,相较于单中括号 [ ... ]

特殊情况:

当使用 `==' 和 `!=' 操作符时,操作符右边的字符串被用作模式并且执行一个匹配,即支持通配符

当使用 `=~' 操作符时,操作符右边的字符串被当作正则表达式来进行匹配

[[ $file == *.log ]] =  [[ $file =~ log$ ]]

1.6 () 与 {} 的用法及区别

(CMD1 ; CMD2;... ;)和 { CMD1 ; CMD2 ; ... ; } 都可以将多个命令组合成一个整体,作为单个命令执行

区别说明
(CMD1 ; CMD2;... ;)开启子shell去执行命令,这也意味着括号内的变量更改不会影响到父shell
{ CMD1 ; CMD2 ; ... ; }使用当前shell去执行命令,可能会影响当前shell的环境

1.7 括号组合使用的区别

  • [[ ]]只能使用&& ||,不能使用-a或-o。&&和||写在括号里或外都可以
  • (( ))与[[ ]]相同,只不过可以省略变量前的$,且只能用于整数比较
  • [ ]既可以使用&& ||,也可以使用-a或-o。但&&和||必须在括号外,-a或-o必须在括号内
括号内连接括号外连接
[ ]  -a  -o &&  ||
[[ ]] &&  ||&&  ||

2、if语句 

2.1 单分支if语句

单分支if语句只包含一个条件,如果条件为真,则执行相应的代码块;否则跳过

#单分支if语句格式:
if  判断条件;
then 
条件为真的分支代码
fi

 2.2 双分支if语句

双分支if语句包含两个分支,一个是条件为真时执行的代码块,另一个是条件为假时执行的代码块

#双分支if语句格式:
if    判断条件; 
then
条件为真的分支代码

else
条件为假的分支代码

fi

 2.3 多分支if语句

多分支if语句使用elif关键字来测试多个条件,并在找到第一个为真的条件时执行相应的代码块

#多分支if语句格式:
if   判断条件1
then
条件1为真的分支代码

elif  判断条件2
then
条件2为真的分支代码

elif  判断条件3
then
条件3为真的分支代码

......
else
以上条件都为假的分支代码

fi

 2.4 shell脚本的if语句案例

案例一

编写脚本检查httpd服务是否开启,如果开启则反馈httpd服务正在运行,否则启动httpd服务

#!/bin/bash
#检查httpd服务是否开启,如果开启则反馈httpd服务正在运行,否则启动httpd服务
systemctl status httpd &> /dev/null
if [ $? -eq 0 ]
then
echo "httpd 服务正在运行"
else
systemctl start httpd
  if [ $? -eq 0 ]
  then
  echo "httpd 服务正常启动"
  else
  echo "httpd 服务异常,启动失败"
  fi
fi

案例二

编写脚本实现安装httpd服务,先判断操作系统的类型,如果是centos系统则使用yum命令安装httpd,如果是ubuntu系统则使用apt命令安装httpd,其他暂不支持

#!/bin/bash
#编写脚本实现安装httpd服务,先判断操作系统的类型,如果是centos系统则使用yum命令安装httpd,如果是ubuntu系统则使用apt命令安装httpd,其他暂不支持

if grep -q centos /etc/os-release
then
yum install httpd -y &>/dev/null
 if [ $? -eq 0 ]
 then
 echo "httpd服务安装成功!"
 else
 echo "httpd服务安装失败!请检查错误!"
 fi
elif grep -q ubuntu /etc/os-release
then
apt install httpd -y &>/dev/null
 if [ $? -eq 0 ]
 then
 echo "httpd服务安装成功!"
 else
 echo "httpd服务安装失败!请检查错误!"
 fi
else
echo "您的操作系统暂不支持安装httpd服务!"
fi

案例三

判断当前用户是否为超级管理员

#!/bin/bash
#判断当前用户是否为超级管理员
if [ "$USER" != "root" ]
then
        echo "非管理员用户无权限操作"
else
echo "您是管理员用户"
fi

案例四

请输入分数,来判断成绩的优良  

#!/bin/bash
#请输入分数,来判断成绩的优良  
#优秀:90~100分  良好:70~89分  60-69 及格:60~69分 不及格:0~59  分数输入错误可重新输入
read -p "请输入你的分数(0~100):" score
if [ $score -ge 90 -a $score -le 100 ];then
echo "优秀"
elif [ $score -ge 70 -a $score -le 89 ];then
echo "良好"
elif [ $score -ge 60 -a $score -le 69 ];then
echo "及格"
elif [ $score -ge 0 -a $score -le 59 ];then
echo "不及格"
else
echo "输入有误!请重新输入分数!"
bash $0
fi

案例五

编写脚本,根据当前时间打印不同的问候语

#!/bin/bash
#编写脚本,根据当前时间打印不同的问候语
h=`date +%H`
if [ $h -ge 6 -a $h -le 10 ];then
echo "早上好"
elif [ $h -ge 11 -a $h -le 13 ];then
echo "中午好"
elif [ $h -ge 14 -a $h -le 18 ];then
echo "下午好"
else
echo "晚上好"
fi

案例六

编写脚本实现石头剪刀布的游戏

#!/bin/bash

read -p "请输入 1(石头) 2(剪刀) 3(布):" h

m=`echo $[RANDOM%3+1]`

if [ $h -eq $m ]
then
echo "平局!"
elif [ $h -eq 1 -a $m -eq 2 -o $h -eq 2 -a $m -eq 3 -o $h -eq 3 -a $m -eq 1 ];then
echo "您赢了!"
else
echo "您输了!"
fi

 案例七

检测系统的用户状态是否正常,有用户也有家目录视为正常,有用户但是没家目录为无用户,其他没有用户则视为该用户不存在

#!/bin/bash

read -p "请输入用户名:" user
sh=`grep $user /etc/passwd | cut -d : -f6`
if grep $user /etc/passwd &>/dev/null
then
  if [ -e $sh ];then
  echo "该用户状态正常"
  else
    read -p "该用户没有家目录,是否删除该用户,请输入[yes/no]:" ask
      if [ $ask == yes ];then
          echo "正在删除用户……"
          userdel $user &>/dev/null
          echo "该用户已删除"
          elif [ $ask == no ];then
          exit
      fi
   fi
else
   echo "该用户不存在!" 
fi

3、case语句

3.1 case语句格式

case语句是一种条件语句,用于检查变量或数值等表达式的取值,并根据这些值执行相应的命令或代码块

case格式:

case  变量值  in
模式1)
分支1
 ;;
PAT2)
分支2
 ;;
......
*)       #支持通配符:*、?、[0-9]、|
默认分支
esac

 3.2 shell脚本的case语句案例

案例一

判断输入的是 yes(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)

方法一: 

#!/bin/bash
#判断输入的是 yes(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)

read -p "请输入 yes 或 no :" i
case $i in
[yY]|[yY][eE][sS])
echo "您输入的是:yes"
;;
[nN]|[nN][oO])
echo "您输入的是:no"
;;
*)
echo "您输入有误请重新输入 yes 或 no"
bash $0
esac

方法二: 

#!/bin/bash
#(y,Y,Yes,yEs,yeS,YEs,YeS,yES,YES) 或者 no(N,n,no,No,nO,NO)
read -p "请输入 yes 或 no :" i
num=`echo $i|tr 'A-Z' 'a-z'`

case $num in
y|yes)
echo "您输入的是:yes"
;;
n|no)
echo "您输入的是:no"
;;
*)
echo "您输入有误请重新输入 yes 或 no"
bash $0
esac

案例二

请输入分数,来判断成绩的优良  

#!/bin/bash
#请输入分数,来判断成绩的优良  
#优秀:90~100分  良好:70~89分  60-69 及格:60~69分 不及格:0~59  分数输入错误可重新输入
read -p "请输入你的分数(0~100):" score
case $score in
[99][0-9]|100)
echo "$score 成绩优秀"
;;          
[89][0-9])  
echo "$score 成绩良好"
;;         
[67][0-9])
echo "$score 成绩合格"
;;    
[0-9]|[1-5][0-9])
echo "$score 成绩不合格"
;;  
*)  
echo "输入有误!请重新输入分数!" 
esac

案例三

编写工具箱,即通过不同的选项可以查看不同的系统信息

#!/bin/bash

cat <<EOF
----------------------------------------
|1.查看系统类型
|2.查看主机名
|3.IP地址
|4.查看磁盘大小
|5.查看内存
|6.查看内核版本
|7.查看CPU型号
|8.退出工具箱
----------------------------------------
EOF

read -p "请输入(1~8)选项:" num

case $num in
1)
cat /etc/redhat-release
echo "------------------------------------"
echo
bash $0
;;

2)
hostname
echo "------------------------------------"
echo
bash $0
;;
3)
ifconfig ens33 | grep netmask | tr -s " " | cut -d " " -f3
echo "------------------------------------"
echo
bash $0
;;
4)
lsblk | grep disk | awk '{print $4}'
echo "------------------------------------"
echo
bash $0
;;
5)
free
echo "------------------------------------"
echo
bash $0
;;
6)
uname -r
echo "------------------------------------"
echo
bash $0
;;
7)
lscpu | grep 型号名称 | tr -s " " | cut -d" " -f2-8
echo "------------------------------------"
echo
bash $0
;;
8)
exit
echo "------------------------------------"
echo
bash $0
;;
esac

案例四

编写脚本实现石头剪刀布的游戏,需显示双方出的结果和输赢情况

#!/bin/bash
key=`echo $[RANDOM%3+1]`
read -p "请输入 1(石头) 2(剪刀) 3(布):" num

case $num in
1)
 num="石头"
;;
2)
 num="剪刀"
;;
3)
 num="布"
;;
*)
echo "您输入错误!请重新输入!"
 exit
;;
esac

case $key in
1)
 key="石头"
;;
2)
 key="剪刀"
;;
3)
 key="布"
;;
esac


if [ $num = "石头" -a $key = "剪刀"  -o $num = "剪刀" -a $key = "布" -o $num = "布" -a $key = "石头" ]
then
echo "机器出的是:$key"
echo "您出的是:$num" 
echo "您赢了!"

elif [ $num = $key ]
then
echo "机器出的是:$key"
echo "您出的是:$num" 
echo "平局!"

else
echo "机器出的是:$key"
echo "您出的是:$num" 
echo "您输了!"
fi

案例五

编写脚本实现点餐

#!/bin/bash
sum=0
PS3="请输入(1-6):"
MENU="
酸菜鱼
佛跳墙
东坡肉
鱼香肉丝
宫保鸡丁
点餐结束
"

select menu in $MENU
do
case $REPLY in
1)
echo "$menu 价格是:68"
let sum+=68
;;
2)
echo "$menu 价格是:50"
let sum+=50 
;;  
3)
echo "$menu 价格是:25"
let sum+=25
;;
4)
echo "$menu 价格是:22"
let sum+=22
;;
5)
echo "$menu 价格是:38"
let sum+=38
;;
6)
echo "点菜结束"
break
;;
*)
echo "点菜错误,请重新选择"
;;
esac
done
echo "总价是$sum"

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值