当前位置: 首页 > news >正文

shell-循环控制-3

Linux Shell 脚本

编程逻辑与控制结构

  • 编程逻辑处理
    • 顺序执行
    • 选择执行
    • 循环执行
      • 将某代码段重复运行多次
      • 重复运行多少次
      • 有进入条件和退出条件
  • shell中控制流结构
    • if … then … else … fi
    • case 语句 ;; esac
    • for 循环
    • until 循环
    • while 循环
      • break 控制
      • continue 控制

if … then … else … fi

  • 示例

    # 用中文描述,  如果if 1大于2, 那就打印echo 对, 否则就else 打印 不对的; fi结束
    if 条件; then 语句; else 语句; fi [root@localhost opt]# if [[ 1 > 2 ]]; then echo "对"; else echo "不对"; fi 
    不对# 也可以用这种方式 Shell 条件逻辑 
    [root@localhost opt]# [[ 222 > 333 ]] && echo "对" || echo "不对"
    不对
    

case

  • 语法

    # case 变量名 in   从上下下看每个 变量名 做一下比较,如果匹配就执行这个逻辑
    case "$变量名" in "模式1") # 当变量值匹配“模式1”时执行的命令 命令1 命令2 ;;  # 结束当前分支(必须用两个分号) "模式2" | "模式3")  # 用 | 表示“模式2或模式3都匹配” # 当变量值匹配模式2或模式3时执行的命令 命令3 ;; *)  # 所有模式都不匹配时(默认情况,类似 else) # 默认执行的命令 echo "没有匹配的选项" ;; 
    esac  # 结束 case 语句(case 的反写) 
    
  • 示例

    [root@localhost opt]# cat -n case.sh 1	#!/usr/bin/env bash2	#3	case $1 in 4	  get1)5	    echo "第一" ;;6	  get2)7	    echo "第二" ;;8	  *)9	    echo "没有这个变量" ;;10	esac
    [root@localhost opt]# bash case.sh get
    没有这个变量
    [root@localhost opt]# bash case.sh get1
    第一
    

for

  • 语法: for 变量名 in 列表; do 循环体 ; done

    • 格式

      • 双小括号方法,即((…))格式,也可以用于算术运算

      • 双小括号方法也可以使bash Shell实现C语言风格的变量操作 i=10 ((i++))

      • for循环的特殊格式:

        for ((控制变量初始化;条件判断表达式;控制变量的修正表达式)); do循环体
        done
        
      • 控制变量初始化:仅在运行到循环代码段时执行一次

      • 控制变量的修正表达式:每轮循环结束会先进行控制变量修正运算,而后再做条件判断

  • 列表

    • 直接给出列表
      • 整数列表
        • {start…end} 如: for i in {1..10}
        • $(seq [start [step]] end) 如 for i in seq 1 10
        • for (( i=0;i<=num;i++))
      • 返回列表命令
        • $(COMMAND)
  • 示例

    • for列表的几种用法

      [root@localhost opt]# for i in {1..10};do echo $i;done# 从1 开始打印1-10
      [root@localhost opt]# for u in `seq 1 1 10`;do echo $u;done
      # 从2 开始打印1-10
      [root@localhost opt]# for u in `seq 2 1 10`;do echo $u;done
      # 从1 开始每次加2,  就是13579
      [root@localhost opt]# for u in `seq 1 2 10`;do echo $u;done[root@localhost opt]# for ((i=0;i<=10;i++ ));do echo $i;done
      
    • 添加10个用户user1-user10,密码为8位随机字符

      echo $RANDOM|/usr/bin/md5sum | /usr/bin/cut -c 2-9
      # 随机生成密码for i in {1..10};dopass=`echo $RANDOM|/usr/bin/md5sum | /usr/bin/cut -c 2-9`count=`cat /etc/passwd  | cut -f1 -d":" | grep "user1$" -c`if [ $count -eq 0 ];thenuseradd user$iecho $pass | passwd --stdin user$i &>/dev/nullecho "user$i   password: $pass" >> ./user.txtelseecho 'user$i 已存在' >> /.user.txtfi
      done
      
    • 编写脚本,提示输入正整数n的值,计算1+2+…+n的总和

      read -p "请输入整数: " num
      sum=0
      for i in `seq 1 1 $num`;do#sum=$[$sum+$i]sum=$(($sum+$i))
      done
      echo $sum
      
    • 计算100以内所有能被3整除的整数之和

      sum=0
      for i in {1..100};do[ $(($i%3)) -eq 0 ] && sum=$(($sum+$i))
      done
      echo $sum
      
    • 打印九九乘法表

      for i in `seq 1 9`;dofor u in `seq 1 9`;do[ $u -le $i ]  && echo -e "$i*$u=$(($i*$u))\t\c"doneecho ""
      done
      

until

是 Shell 脚本中与 while 互补的循环结构,当条件为假时执行循环,直到条件变为真。以下是核心用法和示例

  • 语法

    until [ 条件测试 ]; do # 循环体命令 
    done 
    
    • 先检查条件,若条件为 (非零退出状态),则执行循环体。
    • 每次循环后重新检查条件,一旦条件为 (退出状态为 0),循环终止。
  • 示例

    • 等待文件生成

      until [ -f /tmp/ready.flag  ]; do  echo "等待文件生成..."  sleep 5  
      done  
      echo "文件已就绪!"  # 说明:每 5 秒检查一次文件 /tmp/ready.flag ,直到文件存在后退出循环。
      
    • 服务启动检测

      until systemctl is-active nginx >/dev/null 2>&1; do  echo "Nginx 未运行,尝试启动..."  systemctl start nginx  sleep 3  
      done  
      echo "Nginx 已启动!"  # 说明:循环尝试启动 Nginx,直到服务状态变为 active。
      
    • 超时控制

      timeout=10  
      count=0  
      until [ $count -ge $timeout ]; do  ping -c1 example.com  && break  echo "第 $count 次尝试..."  ((count++))  sleep 1  
      done  
      # 说明:10 秒内尝试 ping 服务器,成功则提前退出,超时后终止。
      
    • 用户输入验证

      until $ ]]; do  read -p "确认操作?(Y/N): " input  
      done  
      # 说明:强制用户输入 Y/N 或 y/n,否则重复提示。
      

while

  • 语法

    while [ 条件表达式 ]; do # 循环体(命令序列) 
    done 
    
    • 每次循环前判断,为 true 则执行循环体,为 false 则退出循环
    • 条件可使用 test 命令([ ])、双括号 (( ))(算术判断)或命令返回值(0 为 true,非 0 为 false)。
  • 冒号说明

    **冒号:**与true 语句不执行任何实际的处理动作,但可用于返回一个出口状态为0 的测试条件。这两个语句常用于While 循环结构的元限循环测试条件,我们在脚本中经常会见到这样的使用

    while :   # 这表示是一个无限循环的过程,所以使用的时候要特别注意,不要形成了死循环,所以一般会定义一个sleep 时间,可以实现秒级别的cron 任务,其语法格式为:# ; 分号允许在一行放多个命令
    while :;do echo 'yep'; sleep 3;done  # 实例了一个无限循环,每隔3秒打印一次yep
    
  • 示例

    • 使用 [ ] 判断(字符串/文件属性等)

      count=1 
      while [ $count -le 5 ]; do  # 当 count ≤ 5 时循环 echo "第 $count 次循环" count=$((count + 1))   # 计数器自增(也可用 count=$[count+1]) 
      done 
      
    • 使用 (( )) 算术判断(更简洁的数字比较)

      i=3 
      while ((i > 0)); do  # 当 i > 0 时循环 echo "倒计时: $i" ((i--))          # i 自减 1 
      done 
      echo "结束!" 倒计时: 3 
      倒计时: 2 
      倒计时: 1 
      结束! 
      
    • 求100以内所有正奇数之和

      o=0
      j=0
      i=0
      while [ $i -lt 101 ];do[ $(($i%2)) -eq 0 ] && o=$(($o+$i)) || j=$(($j+$i))i=$(($i+1))
      doneecho "偶数: " $o
      echo "奇数: " $j
      
    • 遍历文件内容(逐行读取)

      # 读取 file.txt  内容,打印行号和内容 
      line_num=1 
      while read line; do echo "第 $line_num 行: $line" line_num=$((line_num + 1)) 
      done < file.txt   # 通过重定向输入文件 
      # 说明:< file.txt 将文件内容作为 read 命令的输入,每次循环读取一行到变量 line。
      
    • 遍历命令输出(管道传递)

      # 遍历当前目录下的 .txt 文件(每行一个文件名) 
      ls *.txt | while read filename; do echo "找到文件: $filename" # 可添加处理命令,如 cat $filename、mv $filename ./backup/ 等 
      done 
      
    • 判断主机是否在线

      # 编写脚本,提示请输入网络地址,如192.168.0.0,判断输入的网段中主机在线状态,并统计在线和离线主机各多少
      read -p "请输入网段" num
      net=`echo $num | cut  -d'.' -f1-3`
      up=0
      down=0
      while true;dofor i in `seq 1 3`;doip=$net.$iping -c 1 -w 1 $ip &>/dev/nullif [ $? -eq 0 ];then echo "$ip 在线" up=$(($up+1))elseecho "$ip 不在线" down=$(($down+1))fidoneecho "在线主机$up,  不在线主线$down"
      break
      done
      
    • 打印九九乘法表

      i=1
      while [ $i -lt 10 ];dofor u in `seq 1 9`;do[ $u -lt $i ] && echo -e "$u*$i=$(($i*$u))\t\c"done
      echo ""
      i=$(($i+1))
      done
      
    • 查找ip

      #!/bin/bash  
      #
      while true;do# 读取用户输入read -p "请输入一个IPv4地址: " ip_address# 定义IPv4地址的正则表达式ipv4_regex='^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$'# 使用正则表达式判断输入是否为IPv4地址[[ $ip_address =~ $ipv4_regex ]] && break || echo "输入的地址不是一个有效的IPv4地址, 请重新输入"
      donesed -i "/^.*[[:space:]]unicast_peer /{n;s/^\(.*[[:space:]]\)\([0-9].*\)\(#.*\)/\1${ip_address}\1\3/}" test.tx
      
continue
  • 说明

    • 无限循环(条件始终为 true)
    • 需配合 break 手动退出循环,常用于菜单交互持续监听
    • continue [N]:提前结束第N层的本轮循环,而直接进入下一轮判断;最内层为: 第1层
  • 示例

    • 示例1:打印1-10,但跳过偶数

      #!/bin/bash 
      i=1 
      while [ $i -le 10 ]; do if [ $((i % 2)) -eq 0 ]; then  # 如果i是偶数 i=$((i + 1))  # 先自增i(避免死循环) continue      # 跳过当前循环剩余部分,直接进入下一次循环 fi echo "当前数字:$i"  # 只打印奇数 i=$((i + 1)) 
      done # 打印 1,3,5,7,9
      # 当 i 为偶数时,continue 会跳过 echo 语句,直接进入下一次循环判断。
      
    • 读取文件内容,跳过空行和注释行(以 # 开头)

      # 文本 test.txt
      hello 
      # 这是注释行 world 
      # 另一个注释 
      linux #!/bin/bash 
      while IFS= read -r line; do  # 逐行读取文件 # 跳过空行或注释行 if [ -z "$line" ] || [[ "$line" == \#* ]]; then continue  # 跳过当前行,读取下一行 fi echo "有效内容:$line" 
      done < test.txt   # 从文件test.txt 读取输入 # IFS= read -r line 用于完整读取一行(包括空格)。
      # -z "$line" 判断空行,[[ "$line" == \#* ]] 判断以 # 开头的行,满足其一则 continue 跳过。
      
    • 要求用户输入1-5之间的数字,否则重新输入

      #!/bin/bash 
      echo "请输入1-5之间的数字:" 
      while true; do  # 无限循环,直到输入有效 read -r num # 判断是否为数字,且在1-5之间 if ! [[ "$num" =~ ^[0-9]+$ ]] || [ "$num" -lt 1 ] || [ "$num" -gt 5 ]; then echo "输入无效!请重新输入(1-5):" continue  # 跳过剩余部分,重新读取输入 fi echo "你输入的有效数字是:$num" break  # 输入有效,退出循环 
      done 
      
    while true; do  # true 始终返回 0(条件为真) echo "输入 'q' 退出循环" read input if [ "$input" = "q" ]; then break  # 输入 q 时退出循环 fi echo "你输入了: $input" 
    done 
    
break
  • 语法:用于立即终止当前循环并跳出循环体,通常配合条件判断使用

  • 示例

    • 循环打印数字,当数字等于 5 时终止循环。

      #!/bin/bash 
      i=1 
      while true; do  # 无限循环(条件恒为真) echo "当前数字: $i" if [ $i -eq 5 ]; then  # 当 i=5 时 break  # 跳出循环 fi i=$((i + 1))  # i 自增 1 
      done 
      echo "循环结束" 
      
    • 循环读取用户输入,输入 q 时退出。

      #!/bin/bash 
      while true; do read -p "请输入内容(输入 q 退出): " input if [ "$input" = "q" ]; then  # 输入为 "q" 时 echo "收到退出指令,程序结束" break  # 跳出循环 fi echo "你输入的是: $input" 
      done 
      
    • 遍历目录下文件,找到 target.txt 时停止搜索。

      #!/bin/bash 
      file_list=("a.txt"  "b.txt"  "target.txt"  "c.txt")   # 模拟文件列表 
      index=0 while [ $index -lt ${#file_list[@]} ]; do  # 遍历数组 current_file=${file_list[$index]} echo "正在检查: $current_file" if [ "$current_file" = "target.txt"  ]; then  # 找到目标文件 echo "找到目标文件: $current_file,退出搜索" break  # 跳出循环 fi index=$((index + 1)) 
      done 
      
    • 逐行读取文件内容,遇到空行时停止读取。

      data.txt
      第一行 
      第二行 第四行  # 空行后的内容 #!/bin/bash 
      while IFS= read -r line; do  # 逐行读取文件 if [ -z "$line" ]; then  # 判断行是否为空(-z 表示字符串长度为 0) echo "遇到空行,停止读取" break  # 跳出循环 fi echo "读取到: $line" 
      done < data.txt   # 从文件 data.txt  读取输入 ### 打印
      读取到: 第一行 
      读取到: 第二行 
      遇到空行,停止读取 
      
  • 总结

    • while true 可创建无限循环,需通过 break 手动控制退出。
    • break 仅跳出当前最内层循环(嵌套循环中需注意层级)。
    • 通常与 if 条件判断结合,实现“满足特定条件时终止循环”的逻辑。
http://www.dtcms.com/a/562099.html

相关文章:

  • 网站怎样盈利如何注册一家外贸公司
  • 【开题答辩全过程】以 公务员备考系统为例,包含答辩的问题和答案
  • 演员-评论家(Actor-Critic)算法详解与实现
  • 网站开发兼容极速字体颜色推荐wordpress扁平模板下载
  • 东莞 外贸网站建设甘德县wap网站建设公司
  • API 类别 - 小部件
  • 分治思想之快排优化:三分区防退化与剪枝降复杂度
  • 学生作业 制作一个网站网站建设属于什么行业类别
  • Linux进程终止:kill、pkill命令实战(附案例)
  • 上海网站营销好用的网页编辑器
  • LC110 平衡二叉树
  • Auto CAD二次开发——图案填充(函数封装)
  • 【Android】Lottie - 实现炫酷的Android导航栏动画
  • 企业网站服务器租用wordpress 云解析视频教程
  • 【C++】Dev-C++安装步骤(V5.11和V6.3)
  • 阿里云网站用什么做的html在线记账网站模板
  • 企业建网站程序如何使用好单库选品库做网站
  • 深圳开发网站的公司哪家好免费一键网站
  • 如何使用 Ollama 在本地设置和运行 GPT-OSS
  • 合肥网站建设方案托管工业产品设计图片
  • p2p金融网站建设wordpress 适配 手机
  • 各类数据库如何仅授权用户访问元数据
  • 一级做A网站wordpress友情链接分类显示
  • Linux系统管理与常用命令详解
  • 计算机操作系统:用户层的I/O软件
  • 数据中心主机虚拟化
  • TCP/IP是什么?OSI又是什么?
  • wordpress企业网站主题一个网站上面有名优
  • 网站建设 php jsp .net网站内页百度不收录
  • 企业网络营销信息源类别及传递渠道调查东莞网站建设优化