if条件语句的语法
单分支结构
第一种语法:
if <条件表达式>
then
指令
fi
第二种语法:
if <条件表达式>;then
指令
fi
双分支结构
if <条件表达式>
then
指令序列1
else
指令序列2
fi
多分支结构
语法:
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。
复合指令
复合指令:即一串命令。
()和{}都是对一串的命令进行执行,但有所区别:
相同点:
()和{}都是把一串的命令放在括号里面,如果命令在一行命令之间用;号隔开;
()和{}括号里面某个命令的重定向只影响该命令,但括号外的重定向则会被括号里的所有命令影
响。
不同点
()只是对一串命令重新开一个子shell进行执行,{}对一串命令在当前shell执行;
()最后一个命令可以不用分号,{}最后一个命令要用分号;
()里的第一个命令和左边括号不必有空格,{}的第一个命令和左括号之间必须要有一个空格。
exit退出程序
exit语句的基本作用是终止Shell程序的执行。除此之外,exit语句还可以带一个可选的参数,用来指定程
序退出时的状态码。exit语句的基本语法如下:
exit status
其中,status参数表示退出状态,该参数是一个整数值,其取值范围为0~255。与其他的Shell命令一
样,Shell程序的退出状态也储存在系统变量$?中,因此,用户可以通过该变量取得Shell程序返回给父进
程的退出状态码
多条件判断语句case
case语句语法:
case 变量名 in
值1)
指令1
;;
值2)
指令2
;;
值3)
指令3
;;
*)
默认
esac
case语句会将该变量的值与每个值相比较,如果与某个值相等,则执行该value所对应的一组语句。当遇到“;;”符号时,就跳出case语句,执行esac语句后面的语句。如果没有任何一个值与variable的值相匹配,则执行*后面的一组语句。
带列表的for循环语句
步进循环语句for
for循环是最简单,也是最常用的循环语句。与其他的程序设计语言一样,for循环都是初学者在学习循
环结构时的入门课程。for循环通常用于遍历整个对象或者数字列表。按照循环条件的不同,for循环语
句可以分为带列表的for循环、不带列表的for循环以及类C风格的for循环。
带列表的for循环通常用于将一组语句执行已知的次数,其基本语法如下:
for variable in list
do
statement1
statement2
...
done
在上面的语法中,variable称为循环变量,list是一个列表,可以是一系列的数字或者字符串,元素之间
使用空格隔开。do和done之间的所有的语句称为循环体,即循环结构中重复执行的语句。for循环体的
执行次数与list中元素的个数有关。在带列表的for语句执行时,Shell会将in关键字后面的list列表的第1
个元素的值赋给变量variable,然后执行循环体;当循环体中的语句执行完毕之后,Shell会将列表中的
第2个元素的值赋给变量variable,然后再次执行循环体。当list列表中的所有的元素都被访问后,for循
环结构终止,程序将继续执行done语句后面的其他的语句。
Shell允许用户指定for语句的步长。当用户需要另外指定步长时,其基本语法如下:
for varibale in {start..end..step}
do
statement1
statement2
...
done
不带列表的for循环语句
在某些特殊情况下,for循环的条件列表可以完全省略,称为不带列表的for循环语句。如果没有为for循
环提供条件列表,Shell将从命令行获取条件列表。不带列表的for循环语句的一般语法如下:
for variable
do
statement1
statement2
...
done
由于系统变量$@同样可以获取所有的参数,所以以上的语法等价于以下语法:
for variable in $@或$*
do
statement1
statement2
...
done
作业:
- 判断当前主机的CPU生产商,其信息在/proc/cpuinfo文件中vendor_id一行中。如果其生产商为GenuineIntel,就显示其为Intel公司;如果其生产商为AuthenticAMD,就显示其为AMD公司;
分析:将当前主机的信息在/proc/cpuinfo文件中包含vendor_id一行提取出来
[root@localhost ~]# cat /proc/cpuinfo | grep "vendor_id"
vendor_id : AuthenticAMD
vendor_id : AuthenticAMD
vendor_id : AuthenticAMD
vendor_id : AuthenticAMD
发现有四个,而题目只需要一个,进行uniq
[root@localhost ~]# cat /proc/cpuinfo | grep "vendor_id" | uniq
vendor_id : AuthenticAMD
提取过后,我们只需要冒号后面的生厂商
[root@localhost ~]# cat /proc/cpuinfo | grep "vendor_id" | uniq |awk -F: '{print $2}'
AuthenticAMD
生厂商提取出来后,要对其进行判断,如果其生产商为GenuineIntel,就显示其为Intel公司;如果其生产商为AuthenticAMD,就显示其为AMD公司;如果都不是则显示unknow。其中需要注意的是提取出来的生厂商前面存在空白符。
[root@localhost day3]# vim vendor.sh
#!/bin/bash
# 定义vendor,提取到本机的生厂商
vendor=$(cat /proc/cpuinfo | grep "vendor_id" | uniq |awk -F: '{print $2}' )
echo "$vendor"
#进行条件判断,使用了通配符
if [[ "$vendor" =~ [[:space:]]*GenuineIntel$ ]];then
echo "intel"
elif [[ "$vendor" =~ [[:space:]]*AuthenticAMD$ ]];then
echo "AMD"
else
echo "unknow"
fi
[root@localhost day3]# bash vendor.sh
AuthenticAMD
AMD
注:[[:space:]],说明匹配任意一个空白符,包括空格,制表符,换行符以及分页符
- 根据用户输入成绩,判断优良中差(A,B,C,D, 注意边界问题)
85-100 优秀–A
70-84 良好–B
60-69 合格–C
60分以下不合格–D
分析:需要用户输入成绩,使用read,输入成绩后需要判断输入的是否符合成绩的格式如是否为空值,是否在0-100的范围内。判断过后,分数已经确定时在0-100的范围内,在进行判断优良中差。
[root@localhost day3]# vim score.sh
#!/bin/bash
read -p "please input your score : " score
if [ -z "$score" ];then
echo "you must input your score"
exit 1
fi
if [ "$score" -lt 0 -o "$score" -gt 100 ];then
echo "score invalid"
exit 2
fi
if [ "$score" -ge 85 ];then
echo "your score is A"
elif [ "$score" -ge 70 ];then
echo "your score is B"
elif [ "$score" -ge 60 ];then
echo "your score is C"
else
echo "your sorce is D"
fi
[root@localhost day3]# bash score.sh
please input your score :
you must input your score
[root@localhost day3]# bash score.sh
please input your score : 110
score invalid
[root@localhost day3]# bash score.sh
please input your score : 59
your sorce is D
[root@localhost day3]# bash score.sh
please input your score : 69
your score is C
[root@localhost day3]# bash score.sh
please input your score : 85
your score is A
- 判断 sshd 进程是否运行,如果服务启动打印启动,未启动则打印未启动(使用查看进程和端口两种方式)
分析:
如何查看进程是否运行
方法1:查看进程
[root@localhost day3]# ps -ef | grep sshd | grep -v grep | wc -l
3
方法2:查看端口
[root@localhost day3]# ss -lntup | grep -w 22| wc -l
2
[root@localhost day3]# netstat -lntup | grep -w 22 | wc -l
2
进行判断,如果服务启动打印启动,未启动则打印未启动,则当结果大于1时进程在运行,否则进程没有运行并且启动服务。
[root@localhost day3]# vim sshd_running.sh
#!/bin/bash
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
systemctl start sshd >/dev/null
fi
[root@localhost day3]# bash sshd_running.sh
sshd is running
- 检查主机是否存活,并输出结果(使用for循环实现:主机数>=2)
分析:最简单方式是通过ping命令检测
ping -c 2 -W 1 172.10.250. 9 &> /dev/null
通过$?判断,也可以直接 if ping -c 2 -W 1 172.10.250. 9 &> /dev/null测试
[root@bastion ~]# ping -c 2 -W 1 172.25.250.9 &> /dev/null
[root@bastion ~]# echo $?
0
[root@bastion ~]# ping -c 2 -W 1 172.25.250.10 &> /dev/null
[root@bastion ~]# echo $?
0
[root@bastion ~]# ping -c 2 -W 1 172.25.250.11 &> /dev/null
[root@bastion ~]# echo $?
0
[root@bastion ~]# ping -c 2 -W 1 172.25.250.12 &> /dev/null
[root@bastion ~]# echo $?
0
[root@bastion ~]# ping -c 2 -W 1 172.25.250.13 &> /dev/null
[root@bastion ~]# echo $?
0
[root@bastion ~]# ping -c 5 -W 1 172.25.250.14 &> /dev/null
[root@bastion ~]# echo $?
1
[root@bastion ~]# ping -c 5 -W 1 172.25.250.15 &> /dev/null
[root@bastion ~]# echo $?
1
进行判断,如果$?=0,说明主机存活,否则主机没有存活。
主机利用带列表的循环语句进行生成,在循环语句里面进行每个主机的判断,判断是否存活。
[root@bastion ~]# vim ping.sh
#!/bin/bash
for ip in 172.25.250.{9..15}
do
ping -c 2 -W 1 $ip &> /dev/null
if [ $? -eq 0 ];then
echo host $ip is running
else
echo host $ip is not running
fi
done
[root@bastion ~]# ./ping.sh
host 172.25.250.9 is running
host 172.25.250.10 is running
host 172.25.250.11 is running
host 172.25.250.12 is running
host 172.25.250.13 is running
host 172.25.250.14 is not running
host 172.25.250.15 is not running
[root@bastion ~]#
- 编写脚本,判断当前系统剩余内存大小,如果低于100M,邮件报警管理员,使用计划任务,每10分钟检查一次。
分析: 如何获取当前系统的内存大小。
使用free,其中-m为以兆字节为单位显示内存量
[root@localhost day3]# free -m
total used free shared buff/cache available
Mem: 1790 1223 98 8 468 412
Swap: 2047 237 1810
然后只要Mem的剩余内存大小。
方法一:
[root@localhost day3]# free -m | grep 'Mem:' | tr -s " " | cut -d " " -f4
94
方法二:
[root@localhost day3]# free -m | awk '/Mem:/ {print $4}'
94
提取出来后进行条件判断,如果低于100M,则显示剩余内存,并且邮件报警管理员,使用计划任务。该脚本每10分钟进行一次。
[root@localhost day3]# vim free_mem.sh
#!/bin/bash
free=$(free -m | awk '/Mem:/ {print $4}')
if [ "$free" -lt 100 ]
then
echo "free memory $free is less than 100M" | mail -s "Memory alarm" root@localhost
fi
[root@localhost day3]# bash free_mem.sh
[root@localhost day3]# chmod a+rx free_mem.sh
[root@localhost day3]# crontab -e
*/10 * * * * /test/free_mem.sh &>/dev/null