POOPE 发表于 2021-7-26 16:40:13

Linux 云计算集群架构师->第二十一章 结构化命令 case 和 for、while 循环

第二十一章 结构化命令 case 和 for、while 循环
(上课时间2021-07-17,笔记整理时间2021-07-26)
本节所讲内容:
21.1 case-流程控制语句
21.2 循环语句
21.3 while 循环语句和循环嵌套
21.4 实战-3 个 shell 脚本实战

21.1 流程控制语句:case
控制语句:用来实现对程序流程的选择、循环、转向和返回等进行控制。case 是开关语句的一个组成部分;
它是根据变量的不同进行取值比较,然后针对不同的取值分别执行不同的命令操作
适用于多分支,是一个多选择语句
case 变量或表达式 in
​      变量或表达式 1)
​                命令序列 1
​                ;;
​       变量或表达式 2)
​               命令序列 2
​               ;;
​               ……
​               )
​               默认命令序列
esac
case 语句执行流程控制:

执行流程:
首先使用“变量或表达式”的值与值 1 进行比较,若取值相同则执行值 1 后的命令序列,直到遇见双分号“;; ”后跳转至 esac,表示分支结束;
若与值 1 不相匹配,则继续与值 2 进行比较,若取值相同则执行值 2 后的命令序列,直到遇见双分号“;; ”后跳转至 esac,表示结束分支。
依次类推,若找不到任何匹配的值,则执行默认模式“ ) ”后的命令序列,直到遇见 esac 后结束分支
注意事项:
“变量或表达式”后面必须为单词 in,每一个“变量或表达式”的值必须以右括号结束。取值可以为变量或常数。匹配发现取值符合某一模式后,其间所有命令开始执行直至 ;
匹配中的值可以是多个值,通过“|”来分隔
编写一个操作文件的脚本
# vim case.sh
# cat case.sh
File Namme: case-1.shAuthor: xuegod
!/bin/bash
cat <<eof
************
1. backup
2. copy
3. quit
************
eof
read -p "请输入您的选择: " OP
case $OP in
1|backup)

      echo "BACKUP......"
      ;;
    2|copy)
      echo "COPY....."
      ;;
    3|quit)
      exit
      ;;
    *)
      echo erroresac
# bash case.sh
************1. backup 2. copy 3. quit ************请输入您的选择: 1
BACKUP......编写一个启动 apache 服务脚本
# vim case1.sh
# cat case1.sh !/bin/bash
case $1 in
start)

      /usr/bin/systemctl $1 httpd
      /usr/bin/ps aux | grep httpd | grep -v grep
      echo "httpd start"
            ;;
    stop)
      /usr/bin/systemctl $1 httpd
      /usr/bin/ps aux | grep httpd | grep -v grep
      echo "httpd stop"
            ;;
    restart)
      /usr/bin/systemctl $1 httpd
      /usr/bin/ps aux | grep httpd | grep -v grep
      echo "httpd restart"
            ;;
    status)
      /usr/bin/systemctl $1 httpd | grep -v grep
            ;;
    *)
      echo "please input | start | stop | restart | status |"esac
# sh case1.shstatus
21.2 循环语句
21.2.1 for-do-done
1、语法格式:
for var in list         ###:for 后跟 var(var 相当于一个变量)list(相当于一个列表)
do
​    commands
done
或:
for var in list ; do
​   commands
done

2、取值列表有多种取值方式,比如可以直接读取 in 后面的值,默认以空格做分隔
# vim for-1.sh
# cat vim for-1.sh
cat: vim: No such file or directory!/bin/bash
for var in a1 b1 c1 d1
do
echo the text is var
done
# sh for-1.sh
the text is var
the text is var
the text is var
the text is var2、列表中的复杂值,可以使用引号或转义字符”\”来加以约束
# vim for-2.sh
# cat for-2.sh !/bin/bash
for var in a1 b1 'c1 d1' e2 'hello word'
do
echo the text is $var
done
# bash for-2.sh
the text is a1
the text is b1
the text is c1 d1
the text is e2
the text is hello word# vim for-3.sh
# cat for-3.sh !/bin/bash
for var in a1 b\'1 'c1 d1' e2 'hello world'
do
echo the text is $var
done
# bash for-3.sh
the text is a1
the text is b'1
the text is c1 d1
the text is e2
the text is hello world4、从命令中取值
# vim for-4.sh
# cat for-4.sh             #默认以以空格做分隔符!/bin/bash
for i in cat /etc/hosts
do
echo "$i"
done
# sh for-4.sh
127.0.0.1
localhost
localhost.localdomain
localhost4
localhost4.localdomain4
::1
localhost
localhost.localdomain
localhost6
localhost6.localdomain65、自定义 shell 分隔符
默认情况下,base shell 会以空格、制表符、换行符做为分隔符。通过 IFS 来自定义为分隔符指定单个字符做分隔符:
IFS=: #以:冒号做分隔符
可以指定多个
如 IFS='\n: "; ' #这个赋值会将反斜杠、n、冒号、双引号、分号作为字段分隔符。
注:$'\n'与'\n'时的区别
IFS='\n' #将字符\和字符 n 作为字段分隔符。
IFS=$'\n' #使用换行符做为字段分隔符。
# vim for-6.sh         #指定以\n 回车做为 for 语句的分隔符
# cat for-6.sh !/bin/bash
IFS=$'\n'IFS=:                                  #以:冒号做分隔符
for i in cat /etc/hosts
do
echo "$i"
done
# sh for-6.sh
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain66、C 语言风格的 for
语法格式:
for ((i=0;i<10;i++))
do
​   commmands
done
单个变量 输出 1 到 10 之间的数字
# vim for-7.sh
# cat for-7.sh !/bin/bash
for (( i-1 ; i<=10 ; i++ ))   #i=1 只赋值一次。然后执行 i <= 10
do
echo num is $i            # i++在这里执行。 当 for 循环体中所有命令执行完后,再执行 i++
done
# sh for-7.sh
num is
num is 1
num is 2
num is 3
num is 4
num is 5
num is 6
num is 7
num is 8
num is 9
num is 10多个变量, 同时输出 1-9 的升序和降序
# vim for-9.sh
# cat for-9.sh !/bin/bash
for (( a=1,b=9 ; a<10 ; a++,b-- ))
do
echo num is $a - $b
done
# sh for-9.sh
num is 1 - 9
num is 2 - 8
num is 3 - 7
num is 4 - 6
num is 5 - 5
num is 6 - 4
num is 7 - 3
num is 8 - 2
num is 9 - 1
# vim for-9.sh
# cat for-9.sh !/bin/bash
for (( a=1,b=9 ; a<10,b>5; a++,b-- ))
do
echo num is $a - $b
done
# sh for-9.sh
num is 1 - 9
num is 2 - 8
num is 3 - 7
num is 4 - 6
21.3 while 循环语句和循环嵌套
21.3.1 while-do-done
重复测试指令的条件,只要条件成立就反复执行对应的命令操作,直到命令不成立或为假;
语法格式如下:
while 测试命令
do
命令
done

注意:避免陷入死循环 while true
降序输出 10 到 1 的数字
# vim while1.sh
# cat while1.sh !/bin/bash
var=10
while [ $var -ge 0 ]
do
echo $var
var=$[$var-1]
#var=$((var-1))
#let var--
done
# sh while1.sh
10
9
8
7
6
5
4
3
2
1
0自增操作 let var++ 自减操作 let var--

# vim while2.sh
# cat while2.sh !/bin/bas
num=1
while [ $num -lt 10 ]
do
sum=$(( $num$num ))
echo "$num$num = $sum"
((num++))
# let num++
done
# sh while2.sh
1 * 1 = 1
22 = 4
33 = 9
4 * 4 = 16
55 = 25
66 = 36
7 * 7 = 49
88 = 64
99 = 8121.3.2 嵌套循环
例 1:批量添加 a.txt 文件 5 个用户
# vim user.txt         #添加 5 个用户
# cat user.txt
which
cd
ls
df
rm编写脚本的思路
1 明确脚本的功能
2 编写脚本时会使用到那些命令 ? useradd passwd for
3 把变化的数据使用变量表示
4 选择适合的流程控制 (选择 、 循环 、分支)
# vim adduser.sh
# cat adduser.sh !/bin/bash
for name in cat/root/user.txt
#for name in $(cat /root/user.txt)
do
id $name &> /dev/null
if [$? -ne 0 ];then

      useradd $name
      echo "password" | passwd --stdin $name &amp;&gt; /dev/null
      echo "user $name create"
    else
      echo "user $name is exits"
    fidone
# sh adduser.sh
user which create
user cd create
user ls create
user df create
user rm create
# tail -n 5 /etc/shadow      #查看最后5行
which:$6$G909SdgSWDO/zYbw$h8LJDbraCyDtOd4TFzNa.mkSCD/Xmah.J0kS85fwuJsPoYuNUDInox9bDy3QVGNh8bkvKgJHreRtJTQOWOnah.:18834:0:99999:7:::
cd:$6$bW4YMSXRt1ilJVzm$swNCKYBwWJMUgtJ36stlvY1Sx9JpgSQyo4kZHi0lxuHSb0d2zrbk456/EV6ZbJOOqE4THiZ4c45RJxBBoz5VV1:18834:0:99999:7:::
ls:$6$8wqPZT.TNJb.ClSj$Cd.xY2NCs31YSbRnJKLleoHBKoWIDpH0MngrPSU/XIySzBLN/m.qDcjROHRPR/DXPQIdKZRMv2y/5XlcHdLLz/:18834:0:99999:7:::
df:$6$HoS6AF1r/ZWeu9Qi$p/6APXsbbTPGcvwgJxwFdK.4y5LvU3i2HHRK9h4SUXilwIUASgtpj/YlSwHAv2OwZhKHR0wQ7V6hhRfI7KSwF1:18834:0:99999:7:::
rm:$6$PURFT3X3E1FtvE.W$ft1OpXzpJTSTtnusNxlKquUmBmMC2pCK8atcDbENLtOjT9ro0YkeSd94ROp.zi728Q4qZUBFmXmxdq3yE.4qt0:18834:0:99999:7:::注:&> 是正确和错误的信息都重定向到/dev/null 里面,相当于 1> /dev/null 2>&1 这个写法
打印九九乘法表
# vim forfor.sh
# cat forfor.sh !/bin/bash
for i in seq 9
do
    for j in seq $i
do

      echo -n "$i*$j=`echo $(($i*$j))` "
    done
    echo " "done
# sh forfor.sh
1*1=1
21=2 22=4
3*1=3 32=6 33=9
4*1=4 42=8 43=12 4*4=16
51=5 52=10 5*3=15 54=20 55=25
6*1=6 62=12 63=18 6*4=24 65=30 66=36
7*1=7 72=14 73=21 7*4=28 75=35 76=42 7*7=49
81=8 82=16 8*3=24 84=32 85=40 8*6=48 87=56 88=64
9*1=9 92=18 93=27 9*4=36 95=45 96=54 9*7=63 98=72 99=81注:外层循环循环行,内层循环循环列
规律: 内层循环的变量<=外层循环的变量
echo -n 代表不换行

21.4 实战-3 个 shell 脚本实战
21.4.1 实战-将/opt 目录下所有的日志文件全自动打包
# vim log-back.sh
# cat log-back.sh !/bin/bash
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.gz $i &> /dev/null
done
#剪切打包的日志文件到目标目录
mv /var/log/*.gz $DES_DIR
ls -lh $DSC_DIR
echo "The scripts exec end,Files tar successfully!"21.4.2 找出 10.170.80.1-10 网段中,服务器已经关机的 IP 地址
# vim ping.sh
# cat ping.sh !/bin/bash
i=1
for (( i=1;i<=10;i++ ))for I in {1..10}for I in seq 10
do
ping -c 3 10.170.80.$i &> /dev/null
if [ $? -ne 0 ];then

      echo 10.170.80.$i is shutdown
    fidone
# sh ping.sh21.4.3 批量创建帐号并生成随机密码
# vim useradd.sh
# cat useradd.sh !/bin/bash
for i in lsuser{1..10}
do
useradd $i
if [ $? -eq 0 ];then

      echo "create ${i} user is successfully!"
    else
      echo "create ${i} user is failed!"
    fi
    pass=`date +%s|md5sum|cut -c 1-8`
    sleep 1
    echo "$i:$pass" &gt;&gt; /tmp/passwd.log
    echo $pass |passwd --stdin $i &amp;&gt; /dev/null
    if [ $? -eq 0 ];then
      echo " ${i} user change passwd is successfully!"
    else
      echo " ${i} user change passwd is failed!"
    fidone
# sh useradd.sh
create lsuser1 user is successfully!
lsuser1 user change passwd is successfully!
……………………
# cat /tmp/passwd.log
lsuser1:709f2450
lsuser2:b556b6af
lsuser3:7d27d5e9
lsuser4:d9aab737
lsuser5:7453d2fb
lsuser6:7aaecc2d
lsuser7:489905d6
lsuser8:2c100a10
lsuser9:22700f54
lsuser10:acdfdfc7注意:%s 总秒数。起算时间为 1970-01-01 00:00:00 UTC
总结:
21.1 case - 流程控制语句
21.2 for 循环语句
21.3 while 循环语句和循环嵌套
21.4 实战-3 个 shell 脚本实战

文档来源:51CTO技术博客https://blog.51cto.com/u_2999064/3185593
页: [1]
查看完整版本: Linux 云计算集群架构师->第二十一章 结构化命令 case 和 for、while 循环