shell脚本的循环

这篇具有很好参考价值的文章主要介绍了shell脚本的循环。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

shell脚本的循环

除了if…then…fi 这种条件判断式之外,循环可能是程序当中最重要的一环了。循环可以不断地执行某个程序段落,直到用户设置的条件完成为止。所以,重点是那个【条件的完成】是什么,除了这种依据判断式完成与否的不定循环之外,还有另外一种已经固定要跑多少次循环状态,可称为固定循环状态。

while do done、until do done(不定循环)

一般来说,不定循环最常见的就是下面的两种状态了:

while  [ condition ]  # 中括号内的状态就是判断式 
do       # do是循环的开始
         程序段     
done     # done 是循环的结束

while的中文是【当…时】,所以,这种方式说的是【当condition条件成立时,就进行循环,直到condition的条件不成立才停止】的意思,还有另外一种不定循环的方式

until [ condition ]
do
       程序段
done

这种方式恰恰与while相反,它说的是【当condition条件成立时,就终止循环,否则就持续进行循环的程序段】

例题1

假设我要让用户输入yes或是YES才结束程序的执行,否则就一直告诉用户输入字符串

#!/bin/bash
# 程序说明:
#   输入yes/YES停止输出字符串
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shelldir
export PATH
while [ "${yn}" != "yes" -a "${yn}" != "YES"  ]
do
      read -p "请输入yes/YES来停止该程序:" yn
done
      echo -e "\n您已经停止了该程序\a"

上面这个例题当中【当 ${yn} 这个变量不是 “yes” 且 ${yn} 也不是 "YES"时,就进行循环的程序】,如果输入了yes 或YES 就退出循环。

例题2

我们改变一下上述案例使用 until do done 的形式循环程序

#!/bin/bash
# 程序说明:
#   输入yes/YES停止输出字符串
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shelldir
export PATH
until [ "${yn}" == "yes" -o "${yn}" == "YES"  ]
do
      read -p "请输入yes/YES来停止该程序:" yn
done
      echo -e "\n您已经停止了该程序\a"

上面这个例题当中【当 ${yn} 这个变量是"YES" 或是 “yes” 就退出循环】否则就持续进行循环。

例题3

如果我要计算1+2+…+100的结果呢?利用循环

#!/bin/bash
# 程序说明:
#    求1+...+100的和是多少
# 时间:
# 2023/05/04
PAHT=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shelldir
export PATH
s=0
i=0
while [ "${i}" != "100" ]
do
   i=$(($i+1))
   s=$(($s+$i))
done
   echo "1+2+3...+100=${s}"

当你的执行结果为5050这个数据时就对了。

例题4

如果让用户自行输入一个数字,让程序1+2+3…加到你输入的数字为止,该如何编写呢?

#!/bin/bash
# 程序说明:
#    求1+...+到用户输入的那个数为止,求和。
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/root/shelldir
export PATH
read -p "请输入一个数字我将从1+到你输入的这个数字为止:" stdin
s=0
i=0
while [ "${i}" != "${stdin}" ]
do
   i=$((${i}+1))
   s=$((${i}+${s}))
done
  echo "1+2+3...加到你输入的这个数字,和为:${s} " 

是不是很简单,也可以使用until do done 来测试一下

for…do…done(固定循环)

相对于while、until的循环方式是必须要【符合某个条件】的状态,for这种语法,则是【已经知道要进行几次循环】的状态

它的语法为

for  var in con1 con2 con3 .....
do
     程序段
done

以上面的例子来说,这个${var}的变量内容在循环工作时:

  1. 第一次循环时,${var} 的内容为 con1
  2. 第二次循环时,${var} 的内容为 con2
  3. 第三次循环时,${var} 的内容为 con3

例题1

假设我有3种动物,分别是dog、cat、sheep(🐏),我想每一行都输出这样:【There are dogs…】之类的字样

#!/bin/bash
# 程序说明:
# 该程序判断动物园有哪些动物
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:~/shelldir
export PATH
echo -e "今天的动物园有哪些动物呢?"
for animal in dog cat tiger
do
      echo "有${animal}s"
done

例题2

如果我想要找到/etc/passwd 内的第一个字段,能不能通过管道命令的cut识别出单纯的账号名称后,以id分别检查用户的标识符与特殊参数(id 用户名)?

#!/bin/bash
# 程序说明:
# 该程序识别passwd的账户名称后,用id 账户名称查看用户标识符与特殊参数
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:~/shelldir
export PATH
cutpasswd=$(cut -d ':' -f1 /etc/passwd )   # 选取账号名称
for username in ${cutpasswd}               # 开始循环
do
   id ${username}
done

执行结果如下

[root@localhost shelldir]# sh userid.sh 
uid=0(root) gid=0(root)=0(root)
uid=1(bin) gid=1(bin)=1(bin)
uid=2(daemon) gid=2(daemon)=2(daemon)
uid=3(adm) gid=4(adm)=4(adm)
uid=4(lp) gid=7(lp)=7(lp)
uid=5(sync) gid=0(root)=0(root)
uid=6(shutdown) gid=0(root)=0(root)
uid=7(halt) gid=0(root)=0(root)
uid=8(mail) gid=12(mail)=12(mail)
uid=11(operator) gid=0(root)=0(root)
uid=12(games) gid=100(users)=100(users)
.....
...

例题3

假如我利用ping这个可以判断网络状态的命令,来进行网络状态的实际检测时,我想要检测的域名是本机所在的192.168.124.1~192.168.124.100网段,1~100 ,总不会我在for后面输入 1到100吗?

#!/bin/bash
# 程序说明:
# 该程序是检测网段的
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:~/shelldir
export PATH
network="192.168.124"                    # 定义一个域名
for segment in $(seq 1 100)              # 循环 1~100的数字
do
  ip="${network}.${segment}"             # 通过拼接得到一个完整的IP
  ping -c 1 -w 1 ${ip} > /dev/null 2>&1  # ping命令检测当前IP地址的网络状态
  if [ "$?" -eq "0" ]; then              # 如果返回0,则表示主机正常响应
     echo "${ip}是UP的"
  else
     echo "${ip}是DOWN的"             
  fi                                     # 别忘了加fi
done                                     # 和done

上面这一串命令执行后就可以显示出192.168.124.1~192.168.124.100共100台主机目前是否能够与这个太机器互通。如果你的network和我的不一样修改一下就行了,案例中的$(seq 1 100)是连续输出 1~100的数字,也可以写为【{1…100}】

例题4

我想要让用户输入某个目录文件名,然后我找出某目录内的文件名权限,应该怎么做呢?

#!/bin/bash
# 程序说明:
# 该程序是查看目录下的文件权限的
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:~/shelldir
export PATH
read -p "请输入目录文件名:" dir
if [ "${dir}" == "" -o ! -d "${dir}" ]; then
    echo "该${dir}目录不存在,请重新输入"
    exit 1
fi
filelist=$(ls ${dir})      # 列出所有该目录下的文件名称
for filename in ${filelist}
do
   perm=""
   test -r "${dir}/${filename}" && perm="${perm}可读"
   test -w "${dir}/${filename}" && perm="${perm}可写"
   test -x "${dir}/${filename}" && perm="${perm}可执行"
   echo "这个文件 ${dir}/${filename} 权限是${perm}"
done

for…do…done的数值处理

除了上述方法之外,for循环还有另外一种写法,语法如下:

for  (( 初始值; 限制值; 赋值运算 ))
do  
       程序段
done

这种语法适合于数值方面的运算当中,for后面括号内的三串内容意义是:

  • 初始值:某个变量在循环当中的起始值,直接类似 i=1 设置好;
  • 限制值:当变量的值在这个限制值的范围内,就继续进行循环,例如 i<=100
  • 赋值运算:每做一次循环,变量也变化,例如:i=i+1

值得注意的是,在【赋值运算】的设置上,如果每次增加1,则可以使用类似【i++】的方式,就是i每次循环都会增加1的意思。

例题

从1累加到用户输入的数值

#!/bin/bash
# 程序说明:
# 该程序是让用户输入个数字然后累加到用户输入的那个数字,求和
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:~/shelldir
export PATH
read -p "请输入一个数字我会从1+..累加到你输入的那个数字:" usershuzi
s=0
for (( i=1; i<=${usershuzi}; i=i+1 ))
do
    s=$((${s}+${i}))
done
    echo "1+2+3....+${usershuzi}=${s}"

搭配随机数与数组的实验

说到随机数肯定会用到系统给我提供的这个变量${RANDOM}

${RANDOM} 是一个 Bash 内置的环境变量,用于生成一个随机整数。每次调用 ${RANDOM} 时,都会生成一个 0 到 32767之间的随机整数。
可以使用以下方式来获取 ${RANDOM} 的值:

echo ${RANDOM}

也可以将 ${RANDOM} 的值赋值给变量:

my_random=${RANDOM}
echo ${my_random}

由于 ${RANDOM} 只是一个环境变量,所以它的值只在当前 Shell 进程中有效。如果需要在脚本中生成多个随机数,可以在需要的地方调用 ${RANDOM}。

例题1

假如你在家,你不知道吃什么饭,选择困难就很烦,那你就可以写个脚本,脚本搭配随机数来告诉你,今天中午吃啥好?执行这个脚本后,直接跟你说要吃什么。

应该怎么做呢?首先你得要将全部的店家输入到一组数组当中,再通过随机数的处理,去获取可能的数值,再将搭配到的数值显示出来即可。

#!/bin/bash
# 程序说明:
#   打印今天中午吃什么饭
# 时间:
# 2023/05/04
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:~/shelldir
export PATH
eat[1]="红烧肉"           # 定义一个数组
eat[2]="糖醋排骨"
eat[3]="小炒牛肉"
eat[4]="小炒五花肉"
eat[5]="平菇炒香干"
eat[6]="香菇炒芹菜"
eat[7]="喝西北风"
eat[8]="奥里给"
eat[9]="泡面"
eatnum=9                # 定义变量9,表示午餐可选的菜品
check=$(( ${RANDOM} * ${eatnum} /32767 +1))   # 通过随机数计算出今天中午吃什么菜
echo "你中午吃${eat[${check}]}"

上面案例中最重要的就是随机数了,【${RANDOM} * ${eatnum} /32767 +1 】计算出 check 变量的值,${RANDOM} 表示 Bash 内置的环境变量,用于生成一个随机整数,每次调用 ${RANDOM} 时,都会生成一个 0 到 32767 之间的随机整数,这里将其乘以菜品数量,再除以 32767,最后加 1,得到一个 1 到 9 之间的随机整数。

当我们执行上述案例时,就知道自己要吃啥了非常的方便。

例题2

那么如果我想吃3个菜呢?而且不能重复一样的,那应该怎么做?

#!/bin/bash
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:~/shelldir
export PATH
eat[1]="红烧肉"
eat[2]="糖醋排骨"
eat[3]="小炒牛肉"
eat[4]="小炒五花肉"
eat[5]="平菇炒香干"
eat[6]="香菇炒芹菜"
eat[7]="喝西北风"
eat[8]="奥里给"
eat[9]="泡面"
eatnum=9
eated=0
while [ "${eated}" -lt "3" ]; do 
    check=$(( ${RANDOM} * ${eatnum} /32767+1 ))
    mycheck=0
    if [ "${eated}" -ge "1"  ]; then
        for i in $(seq 1 ${eated})
        do
               if [ ${eatedcon[$i]} == $check  ]; then
                      mycheck=1
               fi
        done
    fi
    if [ "${mycheck}" == "0"  ]; then
       echo "你可以吃${eat[${check}]}"
       eated=$((${eated} + 1 ))
       eatedcon[${eated}]=${check}
    fi
done

代码解释

这段脚本用于随机选择三种食物,输出供用户选择。脚本中的变量和数组含义如下:

  • PATH:环境变量,指定可执行文件的搜索路径。

  • eat:数组,包含九种食物。

  • eatnum:变量,表示数组元素个数。

  • eated:变量,表示已经选择的食物数量,初始值为0。

  • check:变量,用于存储随机选择的食物在数组中的索引。

  • mycheck:变量,用于判断已经选择的食物中是否已经包含了当前选中的食物。

  • eatedcon:数组,用于存储已经选择的食物在数组中的索引。

while循环中的逻辑如下:

  • 当已经选择的食物数量小于3时,进行循环。

  • 生成一个随机数check,表示在数组中的索引。

  • 判断当前选中的食物是否已经被选择过,如果是则跳过,否则输出当前选中的食物,并将eated加1,同时将选中的食物在数组中的索引存入eatedcon数组中。

执行结果

[root@k8s-master-node1 shelldir]# sh noon_what_eat.sh 
你可以吃奥里给
你可以吃平菇炒香干
你可以吃糖醋排骨

shell脚本的跟踪与调试

脚本文件在执行之前,最怕就是出现语法错误的问题。那么我们如何调试呢?有没有办法不需要通过直接执行脚本文件就可以判断是否有问题?我们直接用bash的相关参数

sh [-nvx] scripts.sh
选项与参数:
-n:不要执行脚本,仅查询语法的问题
-v:再执行脚本前,先将脚本文件的内容输出到屏幕上
-x:将使用到的脚本内容显示到屏幕上

使用案例

测试dir_perm.sh 有无语法问题

[root@k8s-master-node1 shelldir]# sh -n dir_rwx.sh
# 若没有语法问题,则不会显示任何信息

将noon_what_eat.sh 的执行过程全部列出来文章来源地址https://www.toymoban.com/news/detail-436571.html

[root@k8s-master-node1 shelldir]# sh -x noon_what_eat.sh 
+ PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/bin:/root/shelldir
+ export PATH
+ eat[1]=红烧肉
+ eat[2]=糖醋排骨
+ eat[3]=小炒牛肉
+ eat[4]=小炒五花肉
+ eat[5]=平菇炒香干
+ eat[6]=香菇炒芹菜
+ eat[7]=喝西北风
+ eat[8]=奥里给
+ eat[9]=泡面
+ eatnum=9
+ eated=0
+ '[' 0 -lt 3 ']'
+ check=2
.....
.......

到了这里,关于shell脚本的循环的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Linux中的shell脚本之流程控制&&循环遍历

    3 条件判断 4 流程控制语句 1)if 语句 案例,用户输入用户名和密码,判断用户名是否是admin,密码是否是123,如果正确,则显示登录成功 首先我创建了shell文件,touch getpawer 其中getpawer 是我自己命的名 效果展示如下: 2)case语句:用case语句匹配一个值与一个模式,如果匹配成

    2024年04月16日
    浏览(45)
  • Linux系统Shell脚本第三章:for、while循环及脚本实操

    目录 一、for循环 1、基本格式 2、类C语言格式 二、while循环 1、基本格式 2、死循环语句 三、跳出循环 1、continue跳出循环 2、break跳出循环 四、常用循环脚本实例 1、循环打印9*9乘法表 2、循环ping测试某个网段网络连通性 3、while死循环实现猜数字游戏 用于已知循环次数的场景

    2024年01月16日
    浏览(45)
  • shell脚本——循环语句、sed、函数、数组、免交互expect

    目录 循环语句 for while 与 until sed 基本用法 sed脚本格式 函数 注意事项 定义函数和调用函数 脚本中函数的位置 查看函数 删除函数 函数返回值 函数的传参操作 使用函数文件 递归函数  数组 声明数组 数组切片 免交互expect 定义  基本命令 for循环需要知道循环的次数 格式1:

    2024年02月11日
    浏览(63)
  • 【Shell篇】循环查找某个目录的脚本文件并打印运行

    这段代码是/build/envsetup.sh文件最后一段代码,搜索了源代码中所有的vendorsetup.sh脚本。 这句代码是一个 shell 命令,大致意思是:如果当前目录中存在名为 device 的目录,则在该目录下递归查找深度不超过 4 级的所有文件中,名字为 vendorsetup.sh 的文件,并将find结果按照字母顺

    2024年02月03日
    浏览(44)
  • 3.7 Linux shell脚本编程(分支语句、循环语句)

    目录 分支语句(对标C语言中的if) 多路分支语句(对标C语言中的swich case) 分支语句(对标C语言中的if) 语法结构:          if    表达式                  then  命令表          fi     如果表达式为真, 则执行命令表中的命令; 否则退出if语句, 即执行fi后面的语句。

    2024年02月02日
    浏览(45)
  • shell脚本while循环、read读取控制台输入与函数

    声明: 以下为个人笔记,内容不完全正确,请谨慎参考。 while循环结构 while [条件判断] do 程序 done 脚本示例: 点击查看代码 简易写法: 点击查看代码 read 读取控制台输入 基本语法: read(选项)(参数) 1、选项 -p: 指定读取值时的字符; -t: 指定读取值等待时间(秒-s)如

    2024年04月22日
    浏览(53)
  • 【Linux】Shell脚本之流程控制语句 if判断、for循环、while循环、case循环判断 + 实战详解[⭐建议收藏!!⭐]

    👨‍🎓 博主简介   🏅云计算领域优质创作者   🏅华为云开发者社区专家博主   🏅阿里云开发者社区专家博主 💊 交流社区: 运维交流社区 欢迎大家的加入! 🐋 希望大家多多支持,我们一起进步!😄 🎉如果文章对你有帮助的话,欢迎 点赞 👍🏻 评论 💬 收藏

    2024年02月13日
    浏览(48)
  • 【shell脚本】shell脚本之企业日常机器巡检脚本(进阶实战一)

    恭喜你,找到宝藏博主了,这里会分享shell的学习整过程。 shell 对于运维来说是必备技能之一,它可以提高很多运维重复工作,提高效率。 shell的专栏,我会详细地讲解shell的基础和使用,以及一些比较常用的shell技巧。 有需要的可以从这里开始,可以教会你如何去进行shel

    2024年02月15日
    浏览(39)
  • 【shell脚本】shell脚本之日志切割(进阶实战三)

    恭喜你,找到宝藏博主了,这里会分享shell的学习整过程。 shell 对于运维来说是必备技能之一,它可以提高很多运维重复工作,提高效率。 shell的专栏,我会详细地讲解shell的基础和使用,以及一些比较常用的shell技巧。 有需要的可以从这里开始,可以教会你如何去进行shel

    2024年02月15日
    浏览(42)
  • shell 循环 判断

    for 循环 Shell 脚本里最简单的循环当属 for 循环。最简单的 for 循环如下所示,你只需将变量值依次写在 in 后面即可: 如果要循环的内容是字母表里的连续字母或连续数字,那么就可以按以下语法来写脚本: while 循环 除了 for 循环,Shell 同样提供了 while 循环。对于其它语言,

    2024年01月19日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包