目录
学习笔记:CentOS7学习之二十二: 结构化命令case和for、while循环
本文用于记录学习体会、心得,兼做笔记使用,方便以后复习总结。内容基本完全参考学神教育教材,图片大多取材自学神教育资料,在此非常感谢MK老师和学神教育的优质教学。希望各位因学习需求而要进行转载时,能申明出处为学神教育,谢谢各位!
22.1 流程控制语句:case
控制语句:用来实现对程序流程的选择、循环、转向和返回等进行控制。case是开关语句的一个组成部分;
它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作
适用于多分支,是一个多选择语句
case 变量或表达式 in
变量或表达式1)
命令序列1
;;
变量或表达式2)
命令序列2
;;
……
*)
默认命令序列
esac
case语句执行流程控制:
执行流程:
首先使用“变量或表达式”的值与值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
取值列表有多种取值方式,比如
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
注意:避免陷入死循环 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 :打印九九乘法表
注:外层循环循环行,内层循环循环列
规律: 内层循环的变量<=外层循环的变量[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