博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环
阅读量:4651 次
发布时间:2019-06-09

本文共 11246 字,大约阅读时间需要 37 分钟。

目录

学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环


本文用于记录学习体会、心得,兼做笔记使用,方便以后复习总结。内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK老师和学神教育的优质教学。希望各位因学习需求而要进行转载时,能申明出处为学神教育,谢谢各位!


22.1 流程控制语句:case

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

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

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

case 变量或表达式 in

变量或表达式1)

命令序列1

;;

变量或表达式2)

命令序列2

;;

……

*)

默认命令序列

esac

case语句执行流程控制:

1659632-20190702231541308-1745469317.png

执行流程:

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

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

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

注意事项:

  • “变量或表达式”后面必须为单词in,每一个“变量或表达式”的值必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;;
  • 匹配中的值可以是多个值,通过“|”来分隔

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

[root@CentOs7_64_1_128 tmp]# vim case1.sh#!/bin/bashcat << eof**************** 1.backup **** 2.copy   **** 3.quit   ****************eofread -p "input your choice:" opcase $op in1|backup)        echo "Backup......"        ;;2|copy)        echo "Copy......"        ;;3|quit)        exit 10        ;;*)        echo error[root@CentOs7_64_1_128 tmp]# bash case1.sh**************** 1.backup **** 2.copy   **** 3.quit   ****************input your choice:1Backup......[root@CentOs7_64_1_128 tmp]# bash case1.sh**************** 1.backup **** 2.copy   **** 3.quit   ****************input your choice:2Copy......[root@CentOs7_64_1_128 tmp]# bash case1.sh**************** 1.backup **** 2.copy   **** 3.quit   ****************input your choice:3[root@CentOs7_64_1_128 tmp]# bash case1.sh**************** 1.backup **** 2.copy   **** 3.quit   ****************input your choice:5error

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

[root@CentOs7_64_1_128 tmp]# vim case2.sh#!/bin/bashcase $1 instart)        systemctl $1 httpd        ps -aux|grep httpd        echo "httpd started"        ;;stop)        systemctl $1 httpd        ps -aux|grep httpd        echo "httpd stoped"        ;;status)        systemctl $1 httpd        ;;restart)        systemctl $1 httpd        ps -aux|grep httpd        echo "httpd restarted"        ;;*)        echo "USAGE:$0 start|stop|status|restart"esac[root@CentOs7_64_1_128 tmp]# bash case2.shUSAGE:case2.sh start|stop|status|restart[root@CentOs7_64_1_128 tmp]# bash case2.sh startroot      16077  0.0  1.4 415036 58252 ?        Ssl  14:45   0:01 /usr/sbin/httpd -DFOREGROUNDapache    16081  0.0  0.4 431248 16728 ?        S    14:45   0:00 /usr/sbin/httpd -DFOREGROUNDapache    16083  0.0  0.4 431248 16728 ?        S    14:45   0:00 /usr/sbin/httpd -DFOREGROUNDapache    16084  0.0  0.4 431248 16728 ?        S    14:45   0:00 /usr/sbin/httpd -DFOREGROUNDapache    16085  0.0  0.4 431248 16728 ?        S    14:45   0:00 /usr/sbin/httpd -DFOREGROUNDapache    16086  0.0  0.4 431248 16728 ?        S    14:45   0:00 /usr/sbin/httpd -DFOREGROUNDroot      18406  0.0  0.0 112724   972 pts/0    R+   17:03   0:00 grep httpdhttpd started[root@CentOs7_64_1_128 tmp]# vim case2.sh[root@CentOs7_64_1_128 tmp]# bash case2.sh restartroot      18434 53.0  1.4 415036 58244 ?        Ssl  17:04   0:00 /usr/sbin/httpd -DFOREGROUNDapache    18438  0.0  0.3 428780 12560 ?        R    17:04   0:00 /usr/sbin/httpd -DFOREGROUNDapache    18439  0.0  0.3 428780 12560 ?        R    17:04   0:00 /usr/sbin/httpd -DFOREGROUNDapache    18440  0.0  0.3 428780 12560 ?        R    17:04   0:00 /usr/sbin/httpd -DFOREGROUNDapache    18441  0.0  0.3 428780 12560 ?        R    17:04   0:00 /usr/sbin/httpd -DFOREGROUNDapache    18442  0.0  0.3 428780 12560 ?        R    17:04   0:00 /usr/sbin/httpd -DFOREGROUNDroot      18444  0.0  0.0 112724   972 pts/0    R+   17:04   0:00 grep httpd

22.2 循环语句

22.1.2 for-do-done

for var in list

do

commands

done

或:

for var in list ; do

commands

done

1659632-20190702231600240-83490963.png

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

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

[root@CentOs7_64_1_128 tmp]# vim for1.sh#!/bin/bashfor var in a1 b1 c1 d1do        echo "the text is $var"done[root@CentOs7_64_1_128 tmp]# bash for1.shthe text is a1the text is b1the text is c1the text is d1

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

[root@CentOs7_64_1_128 tmp]# vim for2.sh#!/bin/bashfor i in a1 b1 "c1 d1" e2 "hello world"doecho "the text is $i"done[root@CentOs7_64_1_128 tmp]# bash for2.shthe text is a1the text is b1the text is c1 d1the text is e2the text is hello world[root@CentOs7_64_1_128 tmp]# vim for3.sh#!/bin/bashfor var in a1 b\'1 "c1 d1" e2 "hello world" I\'s a22do        echo "the text is $var"done~     [root@CentOs7_64_1_128 tmp]# bash for3.shthe text is a1the text is b'1the text is c1 d1the text is e2the text is hello worldthe text is I'sthe text is a22

3、从变量中取值

[root@CentOs7_64_1_128 tmp]# vim for4.sh#!/bin/bashlist="a1 b1 c1 d1"for i in $listdo        echo "is a $i"done[root@CentOs7_64_1_128 tmp]# bash for4.shis a a1is a b1is a c1is a d1

4、从命令中取值

[root@CentOs7_64_1_128 tmp]# vim for5.sh #默认以空格为分隔符#!/bin/bashfor i in `cat /etc/hosts`do        echo "$i"done[root@CentOs7_64_1_128 tmp]# bash for5.sh 127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6192.168.87.128CentOs7_64_1_128

5、自定义shell分隔符

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

指定单个字符做分隔符:

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

可以指定多个

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

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

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

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

[root@CentOs7_64_1_128 tmp]# vim for6.sh # 指定以\n回车做为 for语句的分隔符#!/bin/bashIFS=$'\n'for i in `cat /etc/hosts`do        echo "$i"done[root@CentOs7_64_1_128 tmp]# bash for6.sh 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4::1         localhost localhost.localdomain localhost6 localhost6.localdomain6192.168.87.128 CentOs7_64_1_128[root@CentOs7_64_1_128 tmp]# vim for7.sh # 以:冒号做分隔符#!/bin/bashIFS=:list=`head -1 /etc/passwd`for i in $listdo        echo "$i"done[root@CentOs7_64_1_128 tmp]# bash for7.shrootx00root/root/bin/bash

6、C语言风格的for

语法格式:

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

do

commmands

done

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

[root@CentOs7_64_1_128 tmp]# vim for8.sh#!/bin/bashfor ((i=1;i<=10;i++))do        echo "number is $i"done[root@CentOs7_64_1_128 tmp]# bash for8.shnumber is 1number is 2number is 3number is 4number is 5number is 6number is 7number is 8number is 9number is 10

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

[root@CentOs7_64_1_128 tmp]# vim for9.sh#!/bin/shfor((a=1,b=10;a<=10;a++,b--))do        echo "a = $a, b = $b"done[root@CentOs7_64_1_128 tmp]# bash for9.sha = 1, b = 10a = 2, b = 9a = 3, b = 8a = 4, b = 7a = 5, b = 6a = 6, b = 5a = 7, b = 4a = 8, b = 3a = 9, b = 2a = 10, b = 1

22.3 while循环语句和循环嵌套

22.3.1 while-do-done

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

语法格式如下:

while 测试命令

do

命令

done

1659632-20190702231625580-1958914836.png

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

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

[root@CentOs7_64_1_128 tmp]# vim while1.sh#!/bin/bashvar=10while [ $var -gt 0 ]do        echo $var        ((var--))done[root@CentOs7_64_1_128 tmp]# bash while1.sh10987654321

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

自增操作 let var++

自减操作 let var--

[root@CentOs7_64_1_128 tmp]# vim while2.sh#!/bin/bashvar=1while [ $var -lt 10 ]do        echo " $var * $var = $(($var*$var))"        let var++done[root@CentOs7_64_1_128 tmp]# bash while2.sh 1 * 1 = 1 2 * 2 = 4 3 * 3 = 9 4 * 4 = 16 5 * 5 = 25 6 * 6 = 36 7 * 7 = 49 8 * 8 = 64 9 * 9 = 81

22.3.2 嵌套循环

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

[root@CentOs7_64_1_128 tmp]# vim adduser.sh  # 批量添加添加用户名#!/bin/bashIFS=$'\n' # 设置换行符\n作为分隔符i=`cat /tmp/a.txt` # 设置i为a.txt中用户名for name in $ido        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"        fidone[root@CentOs7_64_1_128 tmp]# bash adduser.sh 正在创建信箱文件: 文件已存在user yangjie1 created正在创建信箱文件: 文件已存在user yangjie2 created正在创建信箱文件: 文件已存在user yangjie3 created正在创建信箱文件: 文件已存在user yangjie4 created正在创建信箱文件: 文件已存在user yangjie5 created[root@CentOs7_64_1_128 tmp]# vim deluser.sh #批量删除用户名#!/bin/bashIFS=$'\n'i=`cat /tmp/a.txt`for name in $ido        id $name &> /dev/null         if [ $? -eq 0 ]; then                userdel $name                rm -rf /home/$name                echo "user $name delete sucessful"        else                echo "user $name does not exist"        fidone[root@CentOs7_64_1_128 tmp]# bash deluser.sh user yangjie1 delete sucessfuluser yangjie2 delete sucessfuluser yangjie3 delete sucessfuluser yangjie4 delete sucessfuluser yangjie5 delete sucessful

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

例2 :打印九九乘法表

1659632-20190702231646976-1889032080.png

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

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

[root@centos-7-24 tmp]# vim for-for.sh #!/bin/bashfor i in $(seq 9)do        for j in $(seq $i)        do                echo -n "$i * $j = $(($i*$j)) " # -n不换行        done        echo " " done[root@centos-7-24 tmp]# bash for-for.sh

22.4 实战-2个shell脚本实战

22.4.1 实战-将/var目录下所有的日志文件全自动打包,存放到opt下以日期命名的文件夹中备份

[root@centos-7-24 tmp]# vim optback.sh#!/bin/bashsrcdir="/var/log"desdir="/opt/backup/`date +"%Y%m%d"`"if [ ! -d $desdir ]; then        mkdir -p $desdirfifor i in `find $srcdir -name "*.log"`do        tar -czvf $i.tar.gz $i        mv $i.tar.gz $desdirdone[root@centos-7-24 tmp]# bash optback.sh[root@centos-7-24 tmp]# ll /opt/backup/20190702/总用量 552-rw-r--r--. 1 root root    135 7月   2 22:51 :0-greeter.log.tar.gz-rw-r--r--. 1 root root   4264 7月   2 22:51 :0.log.tar.gz-rw-r--r--. 1 root root   5975 7月   2 22:51 anaconda.log.tar.gz-rw-r--r--. 1 root root  92212 7月   2 22:51 audit.log.tar.gz-rw-r--r--. 1 root root  10704 7月   2 22:51 boot.log.tar.gz-rw-r--r--. 1 root root   1332 7月   2 22:51 ifcfg.log.tar.gz-rw-r--r--. 1 root root 245327 7月   2 22:51 journal.log.tar.gz-rw-r--r--. 1 root root    140 7月   2 22:51 ks-script-lByocF.log.tar.gz-rw-r--r--. 1 root root    141 7月   2 22:51 ks-script-M7ywwD.log.tar.gz-rw-r--r--. 1 root root    128 7月   2 22:51 mariadb.log.tar.gz-rw-r--r--. 1 root root  83266 7月   2 22:51 packaging.log.tar.gz-rw-r--r--. 1 root root   6253 7月   2 22:51 program.log.tar.gz-rw-r--r--. 1 root root  12484 7月   2 22:51 storage.log.tar.gz-rw-r--r--. 1 root root   1759 7月   2 22:51 tuned.log.tar.gz-rw-r--r--. 1 root root    385 7月   2 22:51 vmware-network.1.log.tar.gz-rw-r--r--. 1 root root    385 7月   2 22:51 vmware-network.2.log.tar.gz-rw-r--r--. 1 root root    391 7月   2 22:51 vmware-network.3.log.tar.gz-rw-r--r--. 1 root root    383 7月   2 22:51 vmware-network.log.tar.gz-rw-r--r--. 1 root root   2778 7月   2 22:51 vmware-vmsvc.log.tar.gz-rw-r--r--. 1 root root    167 7月   2 22:51 wpa_supplicant.log.tar.gz-rw-r--r--. 1 root root   4786 7月   2 22:51 X.log.tar.gz-rw-r--r--. 1 root root   5543 7月   2 22:51 Xorg.0.log.tar.gz-rw-r--r--. 1 root root   4771 7月   2 22:51 Xorg.9.log.tar.gz-rw-r--r--. 1 root root  10788 7月   2 22:51 yum.log.tar.gz

22.4.2 实战-找出192.168.234.20-30网段中,服务器已经关机的IP地址

[root@centos-7-24 tmp]# vim ping.sh#!/bin/bashfor((i=20;i<=30;i++))do        ping -c 3 192.168.234.$i &> /dev/null        if [ $? -ne 0 ]; then                echo "192.168.234.$i is shutdown"        else                echo "192.168.234.$i is running"        fidone[root@centos-7-24 tmp]# bash ping.sh192.168.234.20 is shutdown192.168.234.21 is shutdown192.168.234.22 is running192.168.234.23 is running192.168.234.24 is running192.168.234.25 is shutdown192.168.234.26 is shutdown192.168.234.27 is shutdown192.168.234.28 is shutdown192.168.234.29 is shutdown192.168.234.30 is shutdown

END 2019/7/2 23:14:41

转载于:https://www.cnblogs.com/yj411511/p/11123763.html

你可能感兴趣的文章