shell流层控制之条件判断和循环

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

作业:

  1. 判断当前主机的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:]],说明匹配任意一个空白符,包括空格,制表符,换行符以及分页符

  1. 根据用户输入成绩,判断优良中差(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
  1. 判断 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

  1. 检查主机是否存活,并输出结果(使用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 ~]# 
  1. 编写脚本,判断当前系统剩余内存大小,如果低于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
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值