数值、字符串比较、文件状态测试、逻辑组合、if语句结构、循环结构

1 案例1:条件测试操作

1.1 问题

本案例要求参考PPT上的示例,分别练习以下条件测试操作:

  • 字符串匹配
  • 比较整数值的大小
  • 识别文件/目录的状态
  • 多个条件/操作的逻辑组合

1.2 步骤

实现此案例需要按照如下步骤进行。

步骤一:条件测试的基本用法

1)语法格式

使用“test 表达式”或者[ 表达式 ]都可以,注意空格不要缺少。

条件测试操作本身不显示出任何信息。所以可以在测试后查看变量$?的值来做出判断。

步骤二:字符串测试

1)== 比较两个字符串是否相同

检查当前用户是否为root。

当root用户执行时:

[root@svr5 ~]# [ $USER == "root" ]         #测试
[root@svr5 ~]# echo $?                    #查看结果0为对,非0为错

当普通用户执行时:

[zengye@svr5 ~]$ [ $USER == "root" ]
[zengye@svr5 ~]$ echo $?                    #查看结果0为对,非0为错

2)!= 比较两个字符串是否不相同

当普通用户执行时:

[zengye@svr5 ~]$ [ $USER != "root" ] 

当root用户执行时:

[root@svr5 ~]# [ $USER != "root" ]

3)变量为空时:

[ "$c" == abc ]      #如果变量为空,有可能报错,加双引号可以避免
[ -z $c ]          #判断变量是否为空
[ ! -z $c ]        #判断变量是否非空

还有一个-n可以测试变量是否不为空(相当于! -z)。

或者结合&&、||等逻辑操作显示出结果 。

4)一行执行多条命令的情况

# A && B                        #仅当A命令执行成功,才执行B命令
# A || B                        #仅当A命令执行失败,才执行B命令
# A ;  B                        #执行A命令后执行B命令,两者没有逻辑关系

步骤三:多个条件/操作的逻辑组合

1)&&,逻辑与

给定条件必须都成立,整个测试结果才为真。

检查变量X的值是否大于10,且小于30:

[root@svr5 ~]# X=20                      #设置X变量的值为20
[root@svr5 ~]# [ $X -gt 10 ] && [ $X -lt 30 ] && echo "YES"

2)||,逻辑或

只要其中一个条件成立,则整个测试结果为真。

只要/tmp/、/var/spool/目录中有一个可写,则条件成立:

[root@svr5 ~]# [ -w "/tmp/" ] || [ -w "/var/spool/" ] && echo "OK"

还可以按以下方式理解与测试

A && B A、B任务都成功算真

A || B A、B 任务有一个成功算真

touch a b c
ls a  &&  ls b  &&  ls c        #结果是都显示
ls a  ||  ls b  ||  ls c        #结果是显示a 
ls a  &&  ls b  ||  ls c        #结果是显示a和b
ls a  ||  ls b  &&  ls c        #结果是显示a和c
[ root != $USER ]  &&  echo "非管理员不能执行该脚本"  && exit 

步骤四:整数值比较

参与比较的必须是整数(可以调用变量)

1)-eq 比较两个数是否相等。

[root@svr5 ~]# X=20                          #定义一个测试变量
[root@svr5 ~]# [ $X -eq 20 ] && echo "yes" || echo "no"

2)-ne 比较两个数是否不相等。

[root@svr5 ~]# [ $X -ne 20 ] && echo "yes" || echo "no"

3)-gt 比较前面的整数是否大于后面的整数。

[root@svr5 ~]# [ $X -gt 10 ] && echo "yes" || echo "no"

4)-ge 比较前面的整数是否大于或等于后面的整数。

[root@svr5 ~]# [ $X -ge 10 ] && echo "yes" || echo "no"

5)-lt 比较前面的整数是否小于后面的整数。

[root@svr5 ~]# [ $X -lt 10 ] && echo "yes" || echo "no"

6)-le 比较前面的整数是否小于或等于后面的整数。

[root@svr5 ~]# [ $X -le 10 ] && echo "yes" || echo "no"

编写脚本,每2分钟检查服务器的用户数量,如果发生变化则发邮件通知管理员

准备环境:

yum  -y  install  mailx   postfix     #安装邮件客户端软件和服务端程序
systemctl  restart  postfix    #启动邮件服务
echo "测试" | mail -s test root   #编写脚本前,测试下邮件功能是否正常 ,mail -s是发送邮件,test是标题,root是给谁发,echo后面写要发送的邮件内容,如果邮件太多可以删除/var/spool/mail/root文件清空邮箱

编写脚本:

#!/bin/bash
x=$(cat /etc/passwd | wc -l)   #将目前用户数量赋值给变量x
[ $x -gt 29 ] && echo "用户数量发生变化,服务器可能被入  侵" | mail -s test root       #如果目前用户数量大于29,就发邮件给管理员,29是之前查看的用户数量

然后测试,以下命令不是脚本内容,要在命令行中敲,不写在脚本中

chmod  u+x  test01.sh   #然后给脚本加x权限
crontab  -e     #编写计划任务
*/2 * * * *  /opt/test01.sh    #定义每2分钟执行脚本

步骤五:识别文件/目录的状态

1)-e 判断对象是否存在(不管是目录还是文件)

[root@svr5 ~]# [ -e "/opt/a" ] && echo "yes" || echo "no"

2)-d 判断对象是否为目录(存在且是目录)

[root@svr5 ~]# [ -d "/opt/b" ] && echo "yes" || echo "no"

3)-f 判断对象是否为文件(存在且是文件)

[root@svr5 ~]# [ -f "/opt/c" ] && echo "yes" || echo "no"

4)-r 判断对象是否可读

[root@svr5 ~]# [ -r "/opt/a" ] && echo "yes" || echo "no"

5)-w 判断对象是否可写

[root@svr5 ~]# [ -w "/opt/a" ] && echo "yes" || echo "no"

6)-x 判断对象是否具有x权限

[root@svr5 ~]#  [ -x "/opt/a" ] && echo "yes" || echo "no"

注意:-r与-w对root无效

2 案例2:使用if选择结构

2.1 问题

本案例要求编写3个Shell脚本,分别实现以下目标:

  • 检测/if_test/cdrom目录,若不存在则创建
  • 检测并判断指定的主机是否可ping通
  • 从键盘读取一个数值,按情况给出不同结果

2.2 方案

if单分支的语法组成:

if  条件测试;then  
命令序列
fi

if双分支的语法组成:

if  条件测试;then
命令序列1
else  
命令序列2
fi

if多分支的语法组成:

if    条件测试1 ;then  
命令序列1
elif  条件测试2 ;then  
命令序列2
else
命令序列n
fi

2.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:检测/if_test/cdrom目录,若不存在则创建

1)编写脚本如下:

[root@svr5 ~]# vim dir.sh 
#!/bin/bash
dir="/if_test/cdrom/"
if [ ! -d $dir ];then
    mkdir -p $dir
fi 
[root@svr5 ~]# chmod +x dir.sh                  #添加可执行权限

步骤二:使用if双分支

#!/bin/bash
if [ $UID -eq 0 ];then
echo "我是管理员"    
echo ok
else
echo "我不是管理员"
echo no
fi

编写脚本,检测并判断指定的主机是否可ping通

1)分析任务需求

使用ping命令检测目标主机时,可通过$?来判断ping目标主机的成败。

为了节省ping测试时间,可以只发送3个测试包(-c 3)、缩短发送测试包的间隔秒数(-i 0.2)、等待反馈的超时秒数(-W 1)。比如,检查可ping通的主机:

[root@svr5 ~]# ping -c 3 -i 0.2 -W 1 192.168.88.5
[root@svr5 ~]# echo $?                                  #执行状态表示成功
0

2)脚本编写参考如下:

[root@svr5 ~]# vim pinghost.sh 
#!/bin/bash
ping -c 3 -i 0.2 -W 1 $1 &> /dev/null
if [ $? -eq 0 ] ; then
    echo "Host $1 is up."
else
    echo "Host $1 is down."
fi
[root@svr5 ~]# chmod +x pinghost.sh 

3)测试、验证脚本功能

[root@svr5 ~]# ./pinghost.sh 192.168.88.5
Host 192.168.88.5 is up.
[root@svr5 ~]# ./pinghost.sh 192.168.88.50
Host 192.168.88.50 is down.

步骤三:从键盘读取一个数值,按情况给出不同结果

1)脚本编写参考如下:

#!/bin/bash
read -p "询问内容"  x
if 条件;then
    echo "情况一"
elif 条件;then
    echo "情况二"
elif 条件;then
    echo "情况三"
else
    echo "情况四"
fi

3 案例3:使用for循环结构

3.1 问题

本案例要求编写一个Shell脚本chkhosts.sh,利用for循环来检测多个主机的存活状态

3.2 方案

使用for循环,语法结构如下所示:

for  变量名  in  值1 值2 值3        #值的数量决定循环任务的次数
do
    命令序列
done

3.3 步骤

实现此案例需要按照如下步骤进行。

步骤一:练习for循环基本用法

通过循环批量显示5个hello world:

[root@svr5 ~]# vim for01.sh
#!/bin/bash
for i in 1 2 3 4 5
do
        echo "hello world"
done

通过循环批量显示10个abc:

[root@svr5 ~]# vim for02.sh
#!/bin/bash
for i in {1..10}
do
        echo "abc"
done

通过循环批量显示10个数字:

[root@svr5 ~]# vim for03.sh
#!/bin/bash
for i in {1..10}
do
        echo "$i"
done
a=10
for  i  in  `seq $a`            #如果循环次数是通过变量决定可以用seq指令
do
    echo "$i"
done

编写脚本,批量创建账户

#!/bin/bash
for i in $(cat  /opt/name.txt)    #循环批量创建name.txt里面所有账户,文档中每行是一个名字,该文档要提前创建,与脚本在同一目录下即可
do
useradd  $i
done

步骤二:批量检测多个主机的存活状态

1)编写脚本如下:

[root@svr5 ~]# vim chkhosts.sh
#!/bin/bash
for i in {1..10}
do
    ping -c 3 -i 0.2 -W 1 192.168.88.$i &> /dev/null
    if [ $? -eq 0 ] ; then
        echo "88.$i is up."
    else
        echo "88.$i is down."
    fi
done

思考,如何最后输出up与down 的总数?

附加扩展知识(C语言风格的for循环语法格式)

[root@svr5 ~]# vim cfor.sh
#!/bin/bash
for ((i=1;i<=5;i++))
do
   echo $i
done

4 使用while循环结构

while循环属于条件式的执行流程,会反复判断指定的测试条件,只要条件成立即执行固定的一组操作,直到条件变化为不成立为止。所以while循环的条件一般通过变量来进行控制,在循环体内对变量值做相应改变,以便在适当的时候退出,避免陷入死循环。

使用while循环,语法结构如下所示:

while  条件测试       #根据条件的结果决定是否要执行任务,条件测试成功的话就执行,如果失败立刻结束循环
do
    命令序列
done

练习while循环基本用法

脚本1,无心的死循环脚本:

[root@svr5 ~]# vim while01.sh
#!/bin/bash
i=1
while [ $i -le 5 ]
do
        echo "abc"
done
[root@svr5 ~]# chmod +x while01.sh
[root@svr5 ~]# ./while01.sh                #死循环,需要使用Ctrl+C终止脚本

脚本2,死循环的一般格式:

[root@svr5 ~]# vim while02.sh
#!/bin/bash
while :                                    #冒号可以表示条件为真
do
        echo "abc"
sleep 0.1                                #休息0.1秒
done
[root@svr5 ~]# chmod +x while02.sh
[root@svr5 ~]# ./while02.sh                #死循环,需要使用Ctrl+C终止脚本

脚本3,有效循环脚本:

[root@svr5 ~]# vim while03.sh
#!/bin/bash
i=1
while [ $i -le 5 ]
do
        echo "$i"
        let i++
done

你可能感兴趣的:(linux,运维,服务器)