1. while循环基本概述

只要条件成立,就会反复执行循环语句,直到条件不成立时,才会退出。

语法

#第一种
while 条件测试
do
    循环体
done

#第二种
while true
do
    循环体
done

#第三种
while read line
do 
    循环体
done < path.txt


#语法示例脚本

将一个数字1-9升序打印出来

[root@shell /scripts/shell10]# cat while-1.sh
#!/bin/bash
Num=1
while [ $Num -lt 10 ] 
do
    echo $Num
    let Num++
done
[root@shell /scripts/shell10]# sh while-1.sh
1
2
3
4
5
6
7
8
9

打印两个数字,一个升序,一个进行降序

[root@shell /scripts/shell10]# cat while-2.sh
#!/bin/bash
a=1
b=9
while [ $a -lt 10 ]
do
    echo $a $b
    let a++
    let b--
done
[root@shell /scripts/shell10]# sh while-2.sh
1 9
2 8
3 7
4 6
5 5
6 4
7 3
8 2
9 1

2. while循环场景示例

1. 创建10个不同日期的文件。

[root@shell /scripts/shell10]# cat while-3.sh
#!/bin/bash
a=20
while [ $a -lt 30 ] 
do
    date -s "2020/02/$a" &>/dev/null  && touch  $(date +%F).txt
    if [ $? -eq 0 ];then
        echo "$(date +%F).txt 创建成功!"
    else
        echo "$(date +%F).txt 创建失败!"
    fi
    let a++
done

ntpdate  ntp.aliyun.com &>/dev/null

2. 随机点名脚本

[root@shell /scripts/shell10]# cat while-4.sh
#!/bin/bash
read -p "请输入你要进行循环的次数:" Num
if [[ ! $Num =~ ^[0-9]+$ ]];then
    echo "你输入的要进行循环的次数不是一个整数!"
    exit
fi
Count=$(wc -l student.txt | awk '{print $1}')
a=1
while [ $a -le $Num ] 
do
    Random=$((RANDOM % $Count + 1 ))
    sed -n "${Random}p"  student.txt
    sleep 0.5
    let a++
done
Stu_Name=$(sed -n "${Random}p"  student.txt)
echo "天玄子:$Stu_Name"

3. while循环读入文件的方式,进行创建用户

[root@shell /scripts/shell10]# cat while-5.sh
#!/bin/bash
while read line
do
    id $line &>/dev/null
    if [ $? -eq 0 ];then
        echo "用户${line}已经存在!无需再次进行创建!"
    else
        useradd $line  &>/dev/null
        if [ $? -eq 0 ];then
            echo "用户${line}创建成功!"
        else
            echo "用户${line}创建失败!"
        fi
    fi
done < user.txt
[root@shell /scripts/shell10]# sh while-5.sh
用户acc创建成功!
用户abb创建成功!
用户add创建成功!
用户aee创建成功!
[root@shell /scripts/shell10]# tail -4 /etc/passwd
acc:x:1018:1018::/home/acc:/bin/bash
abb:x:1019:1019::/home/abb:/bin/bash
add:x:1020:1020::/home/add:/bin/bash
aee:x:1021:1021::/home/aee:/bin/bash

[root@shell /scripts/shell10]# cat user.txt
daa:ughiergiu
dbb:iruehgier
dcc:iuvgeregi
[root@shell /scripts/shell10]# vim while-6.sh
[root@shell /scripts/shell10]# 
[root@shell /scripts/shell10]# cat while-6.sh
#!/bin/bash
while read line
do
    id ${line%%:*}  &>/dev/null
    if [ $? -eq 0 ];then
        echo "用户${line%%:*}已经存在!"
    else
        useradd  ${line%%:*} &>/dev/null && echo "${line#*:}" |passwd --stdin ${line%%:*} &>/dev/null
        if [ $? -eq 0 ];then
            echo "用户${line%%:*}创建成功!密码设置成功!"
        else
            echo "用户${line%%:*}创建失败!"
        fi
    fi
done < user.txt
[root@shell /scripts/shell10]# sh while-6.sh
用户daa创建成功!密码设置成功!
用户dbb创建成功!密码设置成功!
用户dcc创建成功!密码设置成功!
[root@shell /scripts/shell10]# sh while-6.sh
用户daa已经存在!
用户dbb已经存在!
用户dcc已经存在!

[root@shell /scripts/shell10]# cat user.txt
caa
cbb
cdd
cee

#根据此文件内容进行创建用户,并为其设置一个24位的随机密码  要求密码由数字 大小写字母,特殊符号组成


        Pass=$(mkpasswd  -l 24 -d 6 -c 6 -C 6 -s 6)
        useradd $line  &>/dev/null && echo $Pass | passwd --stdin $line  &>/dev/null
        if [ $? -eq 0 ];then
            echo "用户${line}创建成功!密码设置成功!密码文件为pass.txt"
            echo -e "User:$line \tPass:$Pass"  >> pass.txt  && chmod  400 pass.txt
        else
            echo "用户创建爱你失败!"
        fi
    fi
done < user.txt
[root@shell /scripts/shell10]# sh while-7.sh
用户caa创建成功!密码设置成功!密码文件为pass.txt
用户cbb创建成功!密码设置成功!密码文件为pass.txt
用户cdd创建成功!密码设置成功!密码文件为pass.txt
用户cee创建成功!密码设置成功!密码文件为pass.txt
[root@shell /scripts/shell10]# ll pass.txt 
-r-------- 1 root root 176 2020-03-03 10:51 pass.txt
[root@shell /scripts/shell10]# \cat pass.txt
User:caa     Pass:L17~hMyu1vGT9/|Tg1:cT4*!
User:cbb     Pass:0/HQ"i5cx01=c6;#Xx_Jz0WW
User:cdd     Pass:v90axH_H32AcVe5<>W]9m<R@
User:cee     Pass:N;o>Tm+Lb40J#f$rq54%8CF9

4. 随机猜数字游戏

    1. 随机一个1-100之间的数字

    2. 执行脚本时,提示用户输入一个数字,判断用户输入的是否是数字

    3. 判断用户输入的数字是大了还是小了

    4. 猜错了,继续猜,猜对了退出

    5. 统计出总共失败多少次和总共猜了多少次

while true
do
    循环体
done    

[root@shell /scripts/shell10]# cat while-8.sh
#!/bin/bash
#1.产生一个随机数
Random=$(( RANDOM % 100 + 1 ))
a=0
echo "欢迎你来到老男孩猜数字游戏!"
while true
do
    #2.提示用户输入一个1-100的之间的数字
    read -p "请输入一个[1-100]之间的数字:" Num
    #3. 判断数字是否整数
    if [[ ! $Num =~ ^[0-9]+$ ]];then
        echo "你猜的数字不是一个整数!"
        continue #跳出本次循环下面的命令,继续执行下次循环
    fi
    if [ ! $Num -gt 0 -o ! $Num -le 100 ];then
        echo "你猜的数字不在1-100之间的范围!"
        continue
    fi
    if [ $Num -gt $Random ];then
        echo "很遗憾!你猜的数字大了!继续加油!"
    elif [ $Num -lt $Random ];then
        echo "很遗憾!你猜的数字小了!继续加油!"
    else
        echo "恭喜你!才对了!"
        break
    fi
    let a++
done
echo "你总共猜了$(( $a + 1 ))次!失败了${a}次!"

root@shell /scripts/shell10]# sh while-8.sh
欢迎你来到老男孩猜数字游戏!
请输入一个[1-100]之间的数字:101
你猜的数字不在1-100之间的范围!
请输入一个[1-100]之间的数字:100
很遗憾!你猜的数字大了!继续加油!
请输入一个[1-100]之间的数字:50
很遗憾!你猜的数字小了!继续加油!
请输入一个[1-100]之间的数字:75
很遗憾!你猜的数字大了!继续加油!
请输入一个[1-100]之间的数字:62
很遗憾!你猜的数字大了!继续加油!
请输入一个[1-100]之间的数字:56
很遗憾!你猜的数字大了!继续加油!
请输入一个[1-100]之间的数字:53
很遗憾!你猜的数字小了!继续加油!
请输入一个[1-100]之间的数字:54
很遗憾!你猜的数字小了!继续加油!
请输入一个[1-100]之间的数字:55
恭喜你!才对了!
你总共猜了8次!失败了7次!

5. 使用while 批量探测10.0.0.0网段主机是否通畅!再判断通畅的主机的远程端口是否开放。

[root@shell /scripts/shell10]# cat while-9.sh
#!/bin/bash
#1.调用函数库
[ -f /etc/init.d/functions ] && source  /etc/init.d/functions || echo "函数库文件不存在!"
#2.定义变量
Ip_log=/tmp/ip.log
Port_log=/tmp/port.log
>$Ip_log
>$Port_log
i=1
#3.开始循环
while [ $i -le 254 ]
do
    {
    #4.测试主机网络是否可达
    IP=10.0.0.$i 
    ping -c1 -W1 $IP &>/dev/null
    if [ $? -eq 0 ];then
        action "${IP}地址通畅!"  /bin/true
        echo "$IP" >>$Ip_log
    fi
}&
let i++
sleep 0.2
done
wait
echo "IP地址扫描完毕..................."
echo "开始测试远程端口号..............."
while read line
do
    State=$(nmap -p22 $line |grep -w 22 |awk '{print $2}')
    if [ $State == "open" ];then
        action "IP${line}的远程端口号是开放的........."  /bin/true
        echo "${line} 远程端口是开放的!" >>$Port_log
    else
        action "IP${line}的远程端口号是关闭的........."  /bin/false
    fi
done <$Ip_log
[root@shell /scripts/shell10]# sh while-9.sh
10.0.0.51地址通畅!                                        [  OK  ]
10.0.0.170地址通畅!                                       [  OK  ]
10.0.0.254地址通畅!                                       [  OK  ]
IP地址扫描完毕...................
开始测试远程端口号...............
IP10.0.0.51的远程端口号是开放的.........                   [  OK  ]
IP10.0.0.170的远程端口号是开放的.........                  [  OK  ]
IP10.0.0.254的远程端口号是关闭的.........                  [FAILED]


6. 点菜系统

    1. 有份菜单
    2. 将最后点菜结果显示出来
    3. 某某菜 点了几份
    4. 最后结账的费用

[root@shell /scripts/shell10]# cat while-10.sh
#!/bin/bash
#1.定义菜单
menu() {
cat<<EOF
###########################
1. 夫妻肺片     价格:88元
2. 蒜泥黄瓜     价格:18元
3. 五香牛肉     价格:58元
4. 糖醋排骨     价格:68元
5. 水煮肉片     价格:48元
6. 大盘鸡       价格:98元
7. 锅包肉       价格:58元
8. 帝王蟹       价格:998元
9. 海鲜大咖     价格:398元
0. 结束点菜
###########################
EOF
}
>cai.txt
echo "欢迎来到老男孩大酒店!请根据菜单进行点菜!"
while true
do
    menu
    read -p "请根据上方菜品对应的数字进行点菜:" Num
    if [[ ! $Num =~ ^[0-9]$ ]];then
        echo "本酒店没有你想要点的东西!请根据菜单进行点菜!"
        continue
    fi
    case $Num in
        1)
            clear
            echo "你点了一份夫妻肺片,价格88元。"
            echo "夫妻肺片  88 元">>cai.txt
            ;;
        2)
            clear
            echo "你点了一份蒜泥黄瓜,价格18元。"
            echo "蒜泥黄瓜  18 元">>cai.txt
            ;;
        3)
            clear
            echo "你点了一份五香牛肉,价格58元。"
            echo "五香牛肉  58 元" >>cai.txt
            ;;
        4)
            clear
            echo "你点了一份糖醋排骨,价格68元。"
            echo "糖醋排骨  68 元">>cai.txt
            ;;
        5)
            clear
            echo "你点了一份水煮肉片,价格48元。"
            echo "水煮肉片  48 元" >>cai.txt
            ;;
        6)
            clear
            echo "你点了一份大盘鸡,价格98元。"
            echo "大盘鸡    98 元">>cai.txt
            ;;
        7)
            clear 
            echo "你点了一份锅包肉,价格58元。"
            echo "锅包肉    58 元" >>cai.txt
            ;;
        8)
            clear 
            echo "你点了一份帝王蟹,价格998元。"
            echo "帝王蟹    998 元">>cai.txt
            ;;
        9)
            clear
            echo "你点了一份海鲜大咖,价格398元。"
            echo "海鲜大咖  398 元">>cai.txt
            ;;
        0)
            clear 
            echo "你已经点餐结束!你点的菜品及总价格如下所示:"
            awk '{print $1}' cai.txt |sort | uniq -c |sort -rn | awk '{print "你点了"$2,"总共点了"$1"份!"}'
            awk '{i+=$2}END{print "总价格为:"i"元。"}' cai.txt
            exit
    esac
done

3. 退出循环的语句指令

#1. exit  退出循环,退出脚本

[root@shell /scripts/shell11]# cat exit.sh
#!/bin/bash
for i in {1..3}
do
    echo "123"
    exit
    echo "456"
done
echo "脚本结束"
[root@shell /scripts/shell11]# sh exit.sh
123



#2. break  结束当前循环,或者跳出本次循环,继续执行循环外面的命令

[root@shell /scripts/shell11]# cat break.sh
#!/bin/bash
for i in {1..3}
do
    echo "123"
    break
    echo "456"
done
echo "脚本结束"
[root@shell /scripts/shell11]# sh break.sh
123
脚本结束



#3. continue 忽略本次循环剩余的代码,直接执行下一次循环

[root@shell /scripts/shell11]# cat continue.sh
#!/bin/bash
for i in {1..3}
do
    echo "123"
    continue
    echo "456"
done
echo "脚本结束"
[root@shell /scripts/shell11]# sh continue.sh
123
123
123
脚本结束

#4. 案例

先扫描内网网段的所有主机,存活的主机进行发放本机的公钥

1. 删除旧的密钥对  rm  

2. 本机是否要有公钥,创建密钥对  ssh-keygen  交互式进行创建, 免交互

-f filename #指定私钥文件保存的路径

-N new_passphrase #指定一个新的密码

 ssh-keygen -t rsa -f /root/.ssh/id_rsa -N ""


3. 批量检测内网主机是否存活    ping

4. 如果存活,则发送公钥     确认信息,输入密码  如何进行免交互

 -o StrictHostKeyChecking=no #忽略回复yes的交互(避免第一次交互出现 公钥检查)

 sshpass -p123456 #指定密码为123456,忽略交互

 [root@shell /scripts/shell11]# sshpass -p1  ssh-copy-id -i /root/.ssh/id_rsa.pub  -o StrictHostKeyChecking=no 172.16.1.51


 [root@shell /scripts/shell11]# cat key.sh
#!/bin/bash
#1.调用函数库
[ -f /etc/init.d/functions ] && source  /etc/init.d/functions || echo "函数库文件不存在!"
#2.定义变量
Ip_log=/tmp/ip.log
Port_log=/tmp/port.log
>$Ip_log
>$Port_log
#3.删除旧的密钥对
rm -rf /root/.ssh/
#4.创建新的密钥对
ssh-keygen -t rsa -f /root/.ssh/id_rsa -N "" &>/dev/null
if [ $? -eq 0 ];then
    echo "密钥对创建成功!"
else
    echo "密钥对创建失败!"
    exit
fi
#5.批量探测内网主机
i=1
while [ $i -le 254 ]
do
    {
        #6.测试主机网络是否可达
        IP=10.0.0.$i 
        ping -c1 -W1 $IP &>/dev/null
        if [ $? -eq 0 ];then
            action "${IP}地址通畅!"  /bin/true
            echo "$IP" >>$Ip_log
        fi
    }&
    let i++
    sleep 0.2
done
wait
echo "IP地址扫描完毕..................."
echo "开始测试远程端口号..............."
while read line
do
    State=$(nmap -p22 $line |grep -w 22 |awk '{print $2}')
    if [ $State == "open" ];then
        action "IP${line}的远程端口号是开放的........."  /bin/true
        echo "${line}" >>$Port_log
    else
        action "IP${line}的远程端口号是关闭的........."  /bin/false
    fi
done <$Ip_log
#7. 发送公钥
while read line
do
    sshpass -p1  ssh-copy-id  -p22  -i /root/.ssh/id_rsa.pub  -o StrictHostKeyChecking=no $line  &>/dev/null
    if [ $? -eq 0 ];then
        action "${line}的主机公钥发送成功!"   /bin/true
    else
        action "${line}的主机公钥发送失败!"  /bin/false
        continue
    fi
done <$Port_log
[root@shell /scripts/shell11]# sh key.sh
密钥对创建成功!
10.0.0.6地址通畅!                                         [  OK  ]
10.0.0.7地址通畅!                                         [  OK  ]
10.0.0.52地址通畅!                                        [  OK  ]
10.0.0.170地址通畅!                                       [  OK  ]
10.0.0.254地址通畅!                                       [  OK  ]
IP地址扫描完毕...................
开始测试远程端口号...............
IP10.0.0.6的远程端口号是开放的.........                    [  OK  ]
IP10.0.0.7的远程端口号是开放的.........                    [  OK  ]
IP10.0.0.52的远程端口号是开放的.........                   [  OK  ]
IP10.0.0.170的远程端口号是开放的.........                  [  OK  ]
IP10.0.0.254的远程端口号是关闭的.........                  [FAILED]
10.0.0.6的主机公钥发送成功!                               [  OK  ]
10.0.0.7的主机公钥发送成功!                               [  OK  ]
10.0.0.52的主机公钥发送成功!                              [  OK  ]
10.0.0.170的主机公钥发送成功!                             [  OK  ]
Copyright © 高程程 all right reserved,powered by Gitbook修订于: 2021-05-18 21:14:44

results matching ""

    No results matching ""