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:使用if和exit语句,使得程序在适当的时候退出
[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