• 【Shell】循环结构——for和while循环实例


    Shell可以重复地执行特定的指令,直到特定的条件被满足为止。这重复执行的一组指令就叫做循环
    特点:

    • 首先,循环条件中使用的变量必须是已初始化的,然后在循环中开始执行
    • 每次在循环开始时进行一次测试
    • 重复地执行一个代码块

    (一)for循环语法

    for 循环地基本语法:
    for VAR in iteml item1 item2 ... itemN
    do
    	command1
    	command2
    	...
    	commandN
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    for循环变量的内容的语法

    for VAR in $fileNames
    do
    	command1
    	command2
    	...
    	commandN
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    for循环命令替换的语法

    for VAR in $(Linux-command-name)
    do
    	command1
    	command2
    	...
    	commandN
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    for循环还有三项表达式语法,这种语法与c语言中常见的for循环使用的方法相同,其语法如下:

    for VAR in (( EXP1;EXP2;EXP3))
    do
    	command1
    	command2
    	...
    	commandN
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    上述语法以三项参数循环控制表达式为特征,它由一个初始化式(EXP1),循环测试或条件(EXP2)和一个计算表达式(EXP3)组成。

    (二)for循环实例

    在 for循环中,每次指定列表中的(iterml…itermN)新值被赋给变量VAR 后,for循环都会执行一次,它将重复运行do和 done 之间的所有语句,直到条件不满足时为止。

    这些列表或数值通常是:

    • 字符串;
      数字;
      命令行参数;
      文件名;
      Linux 命令的输出。
      我们来看一个简单的使用for循环的脚本:

    脚本应用示例

    • 任务目标
    • 批量添加用户账号(名称无规律)
    [root@controller ~]# cat uaddfor.sh
    #!/bin/bash
    #######################################################
    #
    #       FILE:uaddfor.sh
    #       USAGE: ./uaddfor.sh
    #
    #   DESCRTPTION:
    #       OPTIONS: --
    #       REPUIREMENTS: --
    #       BUGS: --
    #       NOTES: --
    #       AUTHOR: LEY
    #   ORGANIZATION:
    #       CREATED: 04/17/2024 15:50
    #       REVISION: --
    #####################################################
    
    ULIST=$(cat /root/users.txt)
    for UNAME in $ULIST
    do
            useradd $UNAME
            echo "123456" | passwd --stdin $UNAME
    done
    
    [root@controller ~]# cat users.txt
    zhangsan
    lisi
    wangwu
    
    [root@controller ~]# ./uaddfor.sh
    Changing password for user zhangsan.
    passwd: all authentication tokens updated successfully.
    Changing password for user lisi.
    passwd: all authentication tokens updated successfully.
    Changing password for user wangwu.
    passwd: all authentication tokens updated successfully.
    
    [root@controller ~]# tail -3 /etc/passwd
    zhangsan:x:1001:1001::/home/zhangsan:/bin/bash
    lisi:x:1002:1002::/home/lisi:/bin/bash
    wangwu:x:1003:1003::/home/wangwu:/bin/bash
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43

    在这里插入图片描述

    这个脚本不够完善,我们将其完善一下,判断用户是否存在,是否需要重新创建用户。

    #!/bin/bash
    #######################################################
    #
    #       FILE:uaddfor.sh
    #       USAGE: ./uaddfor.sh
    #
    #   DESCRTPTION:
    #       OPTIONS: --
    #       REPUIREMENTS: --
    #       BUGS: --
    #       NOTES: --
    #       AUTHOR: LEY
    #   ORGANIZATION:
    #       CREATED: 04/17/2024 15:50
    #       REVISION: --
    #####################################################
    ULIST=$(cat /root/users.txt)
    
    for UNAME in $ULIST
    do
        
        id $UNAME &>/dev/null
        if [ $? -eq 0 ]
        then
            echo "用户 $UNAME 已存在。"
            read -p "是否要重新创建 (y/yes|n/no): " ans
            if [ "$ans" == 'yes' ] || [ "$ans" == 'y' ]
            then
                userdel -r $UNAME
                echo "用户 $UNAME 已删除。"
                useradd $UNAME
                echo "123456" | passwd --stdin $UNAME
                echo "用户 $UNAME 创建成功。"
    
            else
                echo "用户 $UNAME 未被删除。"
            fi
        else
            useradd $UNAME
            echo "123456" | passwd --stdin $UNAME
            echo "用户 $UNAME 创建成功。"
        fi
    done
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    再追加日志,将删除用户的信息和日期写入日志

    [root@controller ~]# vim uaddfor.sh
    #!/bin/bash
    #######################################################
    #
    #       FILE:uaddfor.sh
    #       USAGE: ./uaddfor.sh
    #
    #   DESCRTPTION:
    #       OPTIONS: --
    #       REPUIREMENTS: --
    #       BUGS: --
    #       NOTES: --
    #       AUTHOR: LEY
    #   ORGANIZATION:
    #       CREATED: 04/17/2024 15:50
    #       REVISION: --
    #####################################################
    ULIST=$(cat /root/users.txt)
    
    #测试代码,删除/root/users.txt文件中,所有用户
    # for UNAME in $ULIST
    #do
    #       userdel -r $UNAME
    #done
    
    
    #主功能,按照/root/users.txt文件中用户名,新建用户并设置密码为123456
    
    for UNAME in $ULIST
    do
        #判断UNAME是否存在id加用户名如果存在则输出用户信息,不存在则输出不存在,将所有结果丢进/dev/null文件
        id $UNAME &>/dev/null
        if [ $? -eq 0 ]
        then
                #存在则用户输入是否需要重新创建
            echo "用户 $UNAME 已存在。"
            read -p "是否要重新创建 (y/yes|n/no): " ans
            if [ "$ans" == 'yes' ] || [ "$ans" == 'y' ]
            then
                    #输入yes则删除用户重新创建
                userdel -r $UNAME
                    #将删除用户的信息和日期写入日志
                echo "用户 $UNAME 已删除。" >>/etc/rsyslog.conf
                date &>>/etc/rsyslog.conf
                useradd $UNAME
                echo "123456" | passwd --stdin $UNAME
                echo "用户 $UNAME 创建成功。"
    
            else
                echo "用户 $UNAME 未被删除。"
            fi
        else
            useradd $UNAME
            echo "123456" | passwd --stdin $UNAME
            echo "用户 $UNAME 创建成功。"
        fi
    done
                                                                 
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    C语言风格的for循环

    • 通过控制变量,条件成立时循环
    • 步长可控次数
    [root@controller ~]# cat cfor.sh
    #!/bin/bash
    for ((i=1;i<=5;i+=2))
    do
            echo $i
    done
    
    [root@controller ~]# chmod +x cfor.sh
    [root@controller ~]# ./cfor.sh
    1
    3
    5
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 使用 for 循环遍历局域网中的 IP 地址,从 10.0.0.1 到 10.0.0.254。
    • 对每个 IP 地址执行一次 ping 命令,发送一个 ICMP 请求并等待回应,超时时间为1秒。
    • 如果主机对 ICMP 请求有响应(即返回状态码为0),则输出 “Host $host is up.”,表示主机是可达的。
    • 如果主机没有响应,则输出 “Host $host is down.”,表示主机不可达。
    #!/bin/bash
    for ((i=1;i<=254;i+=1)) do
            host="10.0.0.$i"
            ping -c 1 -i 0.2 -W 1 $host &> /dev/null
            if [ $? -eq 0 ]; then
                    echo "Host $host is up."
            else
                    echo "Host $host is down."
            fi
    done
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    (三)while循环语法

    while循环语句用于重复地执行一个命令列表

    while循环语句的语法如下所示:

    while [ CONDITION ]
    do
     command1
     command2
     ...
     commandN
    done
    
    当条件CONDITION为真时,循环体将被逐行执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    (四)while循环实例——菜单驱动程序

    $ cat whilemenu.sh
    #!/bin/bash
    #######################################################
    #
    #       FILE:whilemenu.sh
    #       USAGE: ./whilemenu.sh
    #
    #   DESCRTPTION:
    #       OPTIONS: --
    #       REPUIREMENTS: --
    #       BUGS: --
    #       NOTES: --
    #       AUTHOR: LEY
    #   ORGANIZATION:
    #       CREATED: 04/25/2024 16:04
    #       REVISION: --
    #####################################################
    
    while :
    do
    
    
            clear                                                   #清理终端
            echo "======================================="
            echo "             MAIN - MENU                "
            echo "======================================="
            echo "1. Dispaly date and time."
            echo "2. Dispaly system information."
            echo "3. Dispaly what users are doing."
            echo "4. exit."
    
            read -p "Enter your choice [ 1-4 ]: " choice            #从标准输入中读取用户的输入,并赋值给变量choice
    
            case $choice in
                    1)
                            echo "Today is $(date +%Y-%m-%d)."      #打印当前日期,格式为YYYY-MM-DD
                            echo "Current time : $(date +%H:%M:%S)."        #打印当前时间格式为hh:mm:ss
                            read -p "Press [Enter] key to continue..." readEnterKey#只读入换行符
                            ;;
                    2)
                            uname -a                #打印系统信息
                            read -p "Press [Enter] key to continue..." readEnterKey
                            ;;
                    3)
                            w                       #显示系统当前登录的用户,及用户当前运行命令
                            read -p "Press [Enter] key to continue..." readEnterKey
                            ;;
                    4)
                            echo "Bye!!!"
                            exit 0
                            ;;
                    *)
                            echo "Error: Inalid option!"
                            read -p "Press [Enter] key to continue..." readEnterKey
                            ;;
            esac
    done
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    此脚本的运行结果如下图:

    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

    (五)until循环语句实例

    until循环与while循环类似,也同样基于一个类似的条件。但until循环的判断条件正好与while循环的判断条件相反,until循环在条件为假的时候运行。一旦条件满足,即为真,就会退出循环。until循环的语法如下所示:

    until [ CONDITION ]
    do
     command1
     command2
     ...
     commandN
    done
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    until循环与while循环相比

    • until循环执行直到状态返回0
    • while循环执行直到返回非0状态
    • until循环总是执行至少一次
    $ cat untilloop.sh
    #!/bin/bash
    #######################################################
    #
    #       FILE:untilloop.sh
    #       USAGE: ./untilloop.sh
    #
    #   DESCRTPTION:
    #       OPTIONS: --
    #       REPUIREMENTS: --
    #       BUGS: --
    #       NOTES: --
    #       AUTHOR: LEY
    #   ORGANIZATION:
    #       CREATED: 04/24/2024 16:30
    #       REVISION: --
    #####################################################
    
    
    var=1
    
    until [ $var -gt 3 ]
    do
            echo "The for loop is run $var times."
            var=$(( var + 1 ))
    done
    
    
    $ chmod +x untilloop.sh
    $ ./untilloop.sh
    The for loop is run 1 times.
    The for loop is run 2 times.
    The for loop is run 3 times.
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
  • 相关阅读:
    实战经验分享:如何通过HTTP代理解决频繁封IP问题
    入门力扣自学笔记74 C++ (题目编号710)(未理解)
    【毕业设计】基于单片机的超声波雷达系统
    基于Springboot外卖系统20:前端菜品展示+菜品数量查询
    这篇文章告诉你时光穿梭机特效从年轻变老制作软件
    ShowDoc item_id 未授权SQL注入漏洞复现
    SpringMVC入门
    android | 声明式编程!(笔记)
    Java爬虫利器:Jsoup详细介绍与用法
    SpringBoot请求参数与响应返回值,ResponseEntity<T>自定义响应
  • 原文地址:https://blog.csdn.net/2302_76195174/article/details/137876245