3

第二十一章  结构化命令case和for、while循环

[if !supportLineBreakNewLine]

[endif]

本节所讲内容:

21.1 case -流程控制语句

21.2  循环语句

21.3  while循环语句和循环嵌套

21.4  实战-3个shell脚本实战

 

21.1  流程控制语句:case

控制语句:用来实现对程序流程的选择、循环、转向和返回等进行控制。case是开关语句的一个组成部分;

它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作

适用于多分支,是一个多选择语句

case     变量或表达式in

      

       变量或表达式1)

                     命令序列1

                     ;;

            变量或表达式2)

                     命令序列2

                     ;;

                     ……

                    

*

                     默认命令序列

esac

case语句执行流程控制:

[if !vml]

[endif]

 

执行流程:

首先使用“变量或表达式”的值与值1进行比较,若取值相同则执行值1后的命令序列,直到遇见双分号“;; ”后跳转至esac,表示分支结束;

若与值1不相匹配,则继续与值2 进行比较,若取值相同则执行值2 后的命令序列,直到遇见双分号“;; ”后跳转至esac,表示结束分支。

依次类推,若找不到任何匹配的值,则执行默认模式“ *) ”后的命令序列,直到遇见esac后结束分支

注意事项:

[if !supportLists][endif]“变量或表达式”后面必须为单词in,每一个“变量或表达式”的值必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至;;

[if !supportLists][endif]匹配中的值可以是多个值,通过“|”来分隔

例1:编写一个操作文件的脚本

[root@xuegod63 ~]# cat case-1.sh

#########################################################################

# File Name: case-1.sh

# Author: xuegod

#########################################################################

#!/bin/bash

cat <

****************

** 1. backup **

** 2. copy   **

** 3. quit   **

****************

eof

read -p "Input a choose: " OP

case $OP in

1|backup)

          echo"BACKUP......"

          ;;

2|copy)

          echo"COPY....."

          ;;

3|quit)

          exit

          ;;

*)

          echoerror

esac

 

例2:编写一个启动apache服务脚本

[root@xuegod63 ~]# yum install httpd -y

[root@xuegod63 ~]# vim  case-2.sh

#!/bin/bash

case $1 in

start)

          systemctl$1 httpd

          psaux|grep httpd

          echo"httpd start"

          ;;

stop)

          systemctl$1 httpd

          psaux|grep httpd

          echo"httpd stop"

          ;;

status)

          systemctl$1 httpd

          ;;

restart)

          systemctl$1 httpd

          echo"httpd restart"

          ;;

*)

          echo"USAGE: $0 start|stop|restart"

esac

 

21.2  循环语句

21.2.1  for-do-done

语法格式:

for var in list

do

  commands

done

或:

for var in list ; do

  commands

done

取值列表有多种取值方式,比如

可以直接读取in 后面的值,默认以空格做分隔

[root@xuegod63 ~]# vim for-1.sh

#!/bin/bash

for var in a1 b1 c1 d1

do

      echo thetext is $var

done

 

列表中的复杂值,可以使用 引号或转义字符”/”来加以约束

[root@xuegod63 ~]# cat for-2.sh  

#!/bin/bash

for var in a1 b1 "c1 d1" e2 "helloworld"

do

echo the textis $var

done

[root@xuegod63 ~]# cat for-3.sh

#!/bin/bash

for var in a1 b\'1 "c1 d1" e2 "helloworld" I\'s a22

do

echo the textis $var

done

 

从变量中取值

[root@xuegod63 ~]# cat for-4.sh

#!/bin/bash

list="a1 b1 c1 d1"

for i in $list

do

echo is a $i

done

 

4、从命令中取值

[root@xuegod63 ~]# cat for-5.sh  #以空格做分隔符

#!/bin/bash

for i in `cat /etc/hosts`

do

echo"$i"

done

 

5、自定义shell分隔符

默认情况下,base shell会以空格、制表符、换行符做为分隔符。通过IFS来自定义为分隔符

指定单个字符做分隔符:

IFS=:   #以:冒号做分隔符

可以指定多个

如IFS='\n':;"     #这个赋值会将反斜杠、n、冒号、分号和双引号作为字段分隔符。

 

注:$'\n'与'\n'时的区别

IFS='\n'    #将字符\和字符n作为IFS的换行符。

IFS=$'\n'   #正真的使用换行符做为字段分隔符。

 

 

[root@xuegod63 ~]# cat for-6.sh  #指定以\n回车做为 for语句的分隔符

#!/bin/bash

IFS=$'\n'

for i in `cat /etc/hosts`

do

echo"$i"

done

 [root@xuegod63 ~]# cat for-7.sh   #以:冒号做分隔符

#!/bin/bash

IFS=:

list=`head -1 /etc/passwd`

for i in $list

do

echo $i

done

 

6、C语言风格的for

语法格式:

for ((i=0;i<10;i++))

do

   commmands

done

例1:单个变量。 输出1到10之间的数字

[root@xuegod63 ~]# cat for-8.sh

#!/bin/bash

for ((  i=1 ; i<=10 ; i++  ))

do

echo num is $i

done

 

注:

互动: i++这一条语句在for循环体中哪个位置执行?

 

for ((  i=1 ; i<=10 ;   ))   #i=1只赋值一次。然后执行i <= 10

do

         echo num is $i

i=$(($i+1))    # i++在这里执行。 当for循环体中所有命令执行完后,再执行i++

done

 

 

例2:多个变量。 同时输出1-9的升序和降序

[if !vml]

[endif]

[root@xuegod63 ~]# cat for-8.sh

#!/bin/bash

for ((a=1,b=9 ; a<10 ; a++,b--))

do

echo num is $a- $b

done

 

21.3  while循环语句和循环嵌套

21.3.1  while-do-done

重复测试指令的条件,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假;

语法格式如下:

while 测试命令

do

命令

done

注意:避免陷入死循环  while true

例1:降序输出10到1的数字

[root@xuegod63 ~]# cat while-1.sh

#!/bin/bash

var=10

while [ $var -gt 0 ]

do

         echo $var

         var=$[$var-1]

done

 

例2:输出如下图两数相乘的效果

自增操作  let var++ 

自减操作  let var-- 

[root@xuegod63 ~]# cat while-2.sh

#!/bin/bash

num=1

while [ $num -lt 10 ]

do

       sum=$((  $num * $num ))

       echo  "$num * $num =$sum"

       ((num++))

#       letnum++

done

 

21.3.2  嵌套循环

例1:批量添加a.txt文件5个用户

[root@xuegod63 ~]# vim a.txt   #添加5个用户

mk

cd

ls

find

ln

 

编写脚本的思路

明确脚本的功能

编写脚本时会使用到那些命令 ?  useradd   passwd   for

把变化的数据使用变量表示

选择适合的流程控制  (选择 、 循环 、分支)

 

[root@xuegod63 ~]# cat for-adduser.sh

#!/bin/bash

for name in `cat /root/a.txt`

#for name in $(cat /root/a.txt)

do

        id$name &> /dev/null

        if [$? -ne 0 ];then

               useradd $name

               echo "123456" |passwd --stdin $name &> /dev/null

               echo "user $name created"

 

        else

               echo "user $name is exist"

        fi

done

注:&> 是正确和错误的信息都重定向到/dev/null里面

 

例2 :打印九九乘法表

注:外层循环循环行,内层循环循环列

规律: 内层循环的变量<=外层循环的变量

 

[root@xuegod63 ~]# cat for-for.sh

for i in  `seq9`

do

         for jin `seq $i`

         do

             echo  -n  "$i*$j= `echo $(($i*$j))` "

         done

        echo"  "

done

 

21.4  实战-3个shell脚本实战

 

21.4.1  实战-将/opt目录下所有的日志文件全自动打包

[root@xuegod63 ~]# vim log-back.sh

#!/bin/sh

SRC_DIR=/var/log/

DES_DIR=/opt/backup/`date +%Y%m%d`

if

[ ! -d $DES_DIR ] ; then

        mkdir-p $DES_DIR

fi

for i in `find  $SRC_DIR  -name "*.log"`

do

       tar  czf  $i.tgz $i

done

mv /var/log/*.tgz $DES_DIR

ls -lh $DES_DIR

echo "The scripts exec end, Files tarsuccessfully !"

 

21.4.2  实战-找出192.168.1.1-10网段中,服务器已经关机的IP地址

[root@xuegod63 ~]# vim ping.sh

#!/bin/bash

i=1

for (( i=1;i<10;i++ ))

do

  ping  -c 3  192.168.1.$i &>/dev/null

  if  [ $? -ne 0 ];then

     echo192.168.1.$i is shutdown

  fi

done

 

21.4.3  批量创建帐号并生成随机密码

[root@xuegod63 ~]# vim adduser.sh

#!/bin/bash

for i in xuegoda{1..10}

do

      useradd$i

     pass=`date +%s|md5sum|cut -c 1-8`

      sleep 1

      echo"$i:$pass" >> /tmp/passwd.log

      echo$pass |passwd --stdin $i > /dev/null 2>&1

      if [ $?-eq 0 ];then

        echo"create user is successfully!"

      else

        echo"create user is failed!"

      fi

done

 

 

总结:

21.1 case -流程控制语句

21.2  循环语句

21.3  while循环语句和循环嵌套

21.4  实战-3个shell脚本实战

 

 

你可能感兴趣的:(3)