shell流程控制之条件判断

1 if条件语句的语法及案例

1.1 单分支结构

第一种语法:
if <条件表达式>
then 
   指令
 fi
第二种语法:
if <条件表达式>;then 
	指令
fi

示例1:编写脚本,判断当前系统剩余内存大小,如果低于100M,邮件报警管理员,使用计划任务,每10分钟检查一次。
分析:如何获取当前剩余内存大小
[root@centos-7 ~]# free -m | grep "Mem:" | tr -s " " | cut -d " " -f4
#tr -s 删除所有重复出现字符序列,只保留第一个;即将重复出现字符串压缩为一个字符串
[root@centos-7 ~]# free -m | awk ' /Mem:/ {print $4}'

解答:
[root@centos-7 day4]# vim free_mem.sh
free_mem=sss4(free -m | grep "Mem:" | tr -s " " | cut -d " " -f4)
if [ "$free_mem" -le 100 ];then
  echo "剩余内存:${free_mem},低于100M" | mail -s "内存报警" root@localhost
fi

[root@centos-7 day4]# chmod a+rx free_mem.sh 
[root@centos-7 day4]# crontab -e 
*/10 * * * * /script/day4/free_mem.sh &>/dev/null

示例2:编写脚本,判断当前脚本执行者,如果不是root用户,提示用户脚本需要root用户来执行,并退出。
分析:判断当前脚本执行者
[root@centos-7 day4]# whoami 
root
[root@centos-7 day4]# id -u
0
[root@centos-7 day4]# echo $USER
root
[root@centos-7 day4]# echo $UID
0

解答:
[root@centos-7 day4]# vim test_user.sh
if [ "$USER" != "root" ];then
   echo "please switch user root "
fi
[root@centos-7 day4]# chmod a+rx test_user.sh 
[root@centos-7 day4]# ./test_user.sh 
[root@centos-7 day4]# su - zhl
[zhl@centos-7 ~]$ cd /scripts/day4/
[zhl@centos-7 day4]$ ./test_user.sh 
please switch user root 

1.2 双分支结构

if <条件表达式>
then
   指令序列1
else
   指令序列2
fi

示例1:判断 sshd 进程是否运行,如果服务未启动则启动相应服务。
分析:判断进程是否运行
方法1:查看进程
[root@centos-7 ~]# ps -ef | grep sshd | grep -v grep | wc -l
方法2:查看端口
[root@centos-7 ~]# ss -lnutp | grep 22 | wc -l
[root@centos-7 ~]# netstat -lntup | grep 22 | wc -l

解答:
[root@centos-7 day4]# vim sshd_running.sh
result=`ps -ef | grep sshd | grep -v grep | wc -l`
if [ $result -ge 1 ];then
  echo sshd is running
else
  echo sshd is not running
fi
[root@centos-7 day4]# chmod a+rx sshd_running.sh 
[root@centos-7 day4]# ./sshd_running.sh 
sshd is running

示例2:检查主机是否存活,并输出结果
分析:最简单方式是通过ping命令检测 ping -c 2 -W 1 192.168.168.128 &> /dev/null 通过$?判断,也可以直接 if ping -c 2 -W 1 192.168.233.129 &> /dev/null测试

解答
[root@centos-7 day4]# vim ping.sh
ping -c 2 -w 1 192.168.233.129 &> /dev/null
if [ $? -eq 0 ];then
  echo host 192.168.233.129 is running
else
  echo host 192.168.233.129 is not running
fi
[root@centos-7 day4]# chmod a+rx ping.sh 
[root@centos-7 day4]# ./ping.sh 
host 192.168.233.129 is not running

1.3 多分支结构

if 条件表达式1
then 
  命令序列1
elif 条件表达式2
then 
   命令序列2
elif 条件表达式3
then
   命令序列3
else
   命令序列n
fi
在上面的语法中,当整个if elif语句结构中的第1个条件表达式为真,则执行第1个then子句中的语句statement1;否则,继续下面的判断。如果条件表达式2的值为真,则执行第2个then子句中的语句,以此类推。如果所有的条件表达式的值都为假,则执行最后的else子句中的语句。最后是if elif结构的结束标志fi。

示例1:两个整数比较大小。
方法1:
[root@centos-7 day4]# vim compare.sh
if [ "$1" -eq "$2" ];then
  echo "$1 equal $2"
elif [ "$1" -gt "$2"]
then
  echo "$1 greater than $2"
else
  echo "$1 less than $2"
fi


[root@centos-7 day4]# chmod a+rx compare.sh 
[root@centos-7 day4]# ./compare.sh 20 20
20 equal 20

if [ "$1" -eq "$2" ];then
  echo "$1 equal $2"
elif [ "$1" -gt "$2"]
then
  echo "$1 greater than $2"
else
  echo "$1 less than $2"
fi

方法2:
[root@centos-7 day4]# vim compare1.sh
read -p "please input interger:" a b
if [ "$a" -eq "$b" ];then
  echo "$a equal $b"
elif [ "$a" -gt "$b" ]
then
  echo "$a greater than $b"
else
  echo "$a less than $b"
fi
[root@centos-7 day4]# chmod a+rx compare1.sh 
[root@centos-7 day4]# ./compare1.sh 
please input interger:12 30
12 less than 30

示例2:根据用户输入成绩,判断优良中差。
85-100 优秀--A
70-84 良好--B
60-79 合格--C
60分以下不合格--D
[root@centos-7 day4]# vim level.sh
read -p "please enter a score:" score
if [ -z "$score" ];then
    read -p "you enter nothing,please enter a score:" score
  else
    if [ "$score" -lt 0 -o "$score" -gt 100 ];then
      read "the score should be between 0 and 100,please enter again:" score
    else
      if [ "$score" -ge 85 ];then
        echo "the grade is A"
      elif [ "$score" -ge 70 ];then
        echo "the grade is B"
      elif [ "$score" -ge 60 ];then
        echo "the grade is C"
      else
        echo "the grade is D"
      fi
   fi
fi

[root@centos-7 day4]# chmod a+rx level.sh
[root@centos-7 day4]# ./level.sh 
please enter a score:80
the grade is B

示例3:根据用户输入,判断是数字、字母或其他字符。
[root@centos-7 day4]# vim input.sh
read -p "please enter a character,press enter to continue:" str
if echo "$str" | grep "[a-zA-Z]" >/dev/null
then
  echo "input is letter"
elif echo "$str" | grep "[0-9]" > /dev/null
then
  echo "input is number"
else
  echo "input is other"
fi

[root@centos-7 day4]# chmod +rx input.sh 
[root@centos-7 day4]# ./input.sh 
please enter a character,press enter to continue:2
input is number
[root@centos-7 day4]# ./input.sh 
please enter a character,press enter to continue:e
input is letter
[root@centos-7 day4]# ./input.sh 
please enter a character,press enter to continue:$
input is other

示例4:判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor_id一行中。
如果其生产商为GenuineIntel,就显示其为Intel公司;如果其生产商为AuthenticAMD,就显示其为AMD公司;否则,就显示无法识别;
[root@centos-7 day4]# vim vendor.sh
vendor=$(grep "vendor_id" /proc/cpuinfo |uniq|awk -F: '{print $NF}')
if [[ "$vendor" =~ [[:space:]]*GenuineIntel$ ]]
then
  echo "intel"
elif [[ "$vendor" =~ [[:space:]]*AuthenticAMD$ ]]
then
  echo "AMD"
else
  echo "unknow"
fi
[root@centos-7 day4]# chmod +rx vendor.sh 
[root@centos-7 day4]# ./vendor.sh 
intel
说明:=~表示对后面的正则表达式进行匹配

2 复合指令

复合指令:即一串命令
()和{}都是对一串命令进行执行,但有所区别:

  • 相同点
    ()和{}都是那一串命令放在括号里面,如果命令在一行命令之间用;号隔开
    ()和{}括号里面某个命令的重定向只影响该命令,但括号外的重定向会被括号里的所有命令影响

  • 不同点
    ()只是对一串命令重新开一个子shell进行执行;{}对一串命令在当前shell执行
    ()最后一个命令可以不用分号,{}最后一个命令要用分号;
    ()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必须要有一个空格。

[root@centos-7 day4]# (pwd;cd /tmp;pwd)
/scripts/day4
/tmp
[root@centos-7 day4]# { pwd;cd /tmp;pwd; }
/scripts/day4
/tmp
[root@centos-7 tmp]# (v1=test1;v2=test2;echo $v1>a;echo $v2)
test2
[root@centos-7 tmp]# cat a
test1
[root@centos-7 tmp]# 
[root@centos-7 tmp]# (v1=test1;v2=test2;echo $v1;echo $v2)>a
[root@centos-7 tmp]# cat a
test1
test2
[root@centos-7 tmp]# { v1=test1;v2=test2;echo $v1>a;echo $v2; }
test2
[root@centos-7 tmp]# cat a
test1
[root@centos-7 tmp]# { v1=test1;v2=test2;echo $v1;echo $v2;}>a
[root@centos-7 tmp]# cat a
test1
test2

3 exit退出程序

exit语句的基本作用是终止Shell程序的执行。除此之外,exit语句还可以带一个可选的参数,用来指定程序退出时的状态码。
exit语句的基本语法如下:
exit status
status参数表示退出状态,该参数是一个整数值,其取值范围为0~255。与其他的Shell命令一样,Shell程序的退出状态也储存在系统变量$?中,因此,用户可以通过该变量取得Shell程序返回给父进程的退出状态码

示例1:演示在不同的情况下,程序返回不同的状态码

[root@centos-7 day4]# vim 10.sh
#!/bin/bash
echo hello world
echo $?
aa
echo $?
exit 120
[root@centos-7 day4]# chmod +rx 10.sh 
[root@centos-7 day4]# ./10.sh 
hello world
0
./10.sh:行11: aa: 未找到命令
127


示例2:使用ifexit语句,使得程序在适当的时候退出
[root@centos-7 day4]# vim 11.sh
#!/bin/bash
if [ -e "$1" ]
then
  echo "file $1 exists"
  exit 1
else
  touch "$1"
  echo "file $1 has been created"
  exit 0
fi

4 多条件判断语句

case语句语法:
case 变量名 in
	值1)
	 指令1
	;;
	值2)
	 指令2
	;;
	值3)
	 指令3 
	;;
	*)
	默认 
esac

case语句会将该变量的值与每个值相比较,如果与某个值相等,则执行该value所对应的一组语句。当遇到“;;”符号时,就跳出case语句,执行esac语句后面的语句。如果没有任何一个值与variable的值相匹配,则执行*后面的一组语句。

示例1:由用户从键盘输入一个字符,并判断该字符是否为字母、数字或者其他字符, 并输出相应的提示信息。

[root@centos-7 day4]# vim input1.sh
read -p "please enter a character,press enter to continue:" key
case "$key" in
   [a-z]|[A-Z])
      echo "input is letter"
   ;;
   [0-9])
     echo "input is number"
   ;;
   *)
     echo "input is other characters"
esac

[root@centos-7 day4]# chmod +rx input1.sh 
[root@centos-7 day4]# ./input1.sh 
please enter a character,press enter to continue:1
input is number
[root@centos-7 day4]# ./input1.sh 
please enter a character,press enter to continue:av
input is other characters
[root@centos-7 day4]# ./input1.sh 
please enter a character,press enter to continue:q
input is letter

示例2:将判断分数范围多分支语句用case语句实现

[root@centos-7 day4]# vim level1.sh
#!/bin/bash
read -p "please enter your score (0-100):" grade
case "$grade" in
  8[5-9]|9[0-9]|100)
     echo "A"
  ;;
  7[0-9]|8[0-4])
     echo "B"
  ;;
  6[0-9])
    echo "C"
  ;;
  *)
    echo "D"
 esac
 
[root@centos-7 day4]# chmod +rx level1.sh 
[root@centos-7 day4]# ./level1.sh 
please enter your score (0-100):90
A
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值