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

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

特点:

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

循环实例

(一)for循环语法

javascript 复制代码
for 循环地基本语法:
for VAR in iteml item1 item2 ... itemN
do
	command1
	command2
	...
	commandN
done

for循环变量的内容的语法

javascript 复制代码
for VAR in $fileNames
do
	command1
	command2
	...
	commandN
done

for循环命令替换的语法

javascript 复制代码
for VAR in $(Linux-command-name)
do
	command1
	command2
	...
	commandN
done

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

javascript 复制代码
for VAR in (( EXP1;EXP2;EXP3))
do
	command1
	command2
	...
	commandN
done

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

(二)for循环实例

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

这些列表或数值通常是:

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

脚本应用示例

  • 任务目标
  • 批量添加用户账号(名称无规律)
javascript 复制代码
[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

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

javascript 复制代码
#!/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

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

javascript 复制代码
[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
                                                             

C语言风格的for循环

  • 通过控制变量,条件成立时循环
  • 步长可控次数
javascript 复制代码
[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
  • 使用 for 循环遍历局域网中的 IP 地址,从 10.0.0.1 到 10.0.0.254。
  • 对每个 IP 地址执行一次 ping 命令,发送一个 ICMP 请求并等待回应,超时时间为1秒。
  • 如果主机对 ICMP 请求有响应(即返回状态码为0),则输出 "Host $host is up.",表示主机是可达的。
  • 如果主机没有响应,则输出 "Host $host is down.",表示主机不可达。
javascript 复制代码
#!/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

(三)while循环语法

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

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

javascript 复制代码
while [ CONDITION ]
do
 command1
 command2
 ...
 commandN
done

当条件CONDITION为真时,循环体将被逐行执行

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

javascript 复制代码
$ 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

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





(五)until循环语句实例

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

javascript 复制代码
until [ CONDITION ]
do
 command1
 command2
 ...
 commandN
done

until循环与while循环相比

  • until循环执行直到状态返回0
  • while循环执行直到返回非0状态
  • until循环总是执行至少一次
javascript 复制代码
$ 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 小时前
ns-3仿真之应用层(五)
服务器·网络·tcp/ip·ns3
嵩山小老虎2 小时前
Windows 10/11 安装 WSL2 并配置 VSCode 开发环境(C 语言 / Linux API 适用)
linux·windows·vscode
Fleshy数模2 小时前
CentOS7 安装配置 MySQL5.7 完整教程(本地虚拟机学习版)
linux·mysql·centos
a41324472 小时前
ubuntu 25 安装vllm
linux·服务器·ubuntu·vllm
Configure-Handler2 小时前
buildroot System configuration
java·服务器·数据库
津津有味道3 小时前
易语言TCP服务端接收刷卡数据并向客户端读卡器发送指令
服务器·网络协议·tcp·易语言
Fᴏʀ ʏ꯭ᴏ꯭ᴜ꯭.3 小时前
Keepalived VIP迁移邮件告警配置指南
运维·服务器·笔记
Genie cloud4 小时前
1Panel SSL证书申请完整教程
服务器·网络协议·云计算·ssl
一只自律的鸡4 小时前
【Linux驱动】bug处理 ens33找不到IP
linux·运维·bug
17(无规则自律)4 小时前
【CSAPP 读书笔记】第二章:信息的表示和处理
linux·嵌入式硬件·考研·高考