【shell脚本】沐风晓月跟你聊聊shell脚本中的while循环

news/2024/7/4 7:47:49 标签: shell, linux, 运维, 云原生

前言

上篇文章我们探讨了for循环,如果你还没有开始学习,可以点击链接学习:https://blog.csdn.net/wisdom_futrue/article/details/131402075

今天我们一起来聊聊while循环。

文章目录

    • 前言
  • while循环的介绍
  • while的语法结构
  • 案例实战
    • 1.循环打印企业官网,read指令用于读取行或者读取变量
    • 2. 实现循环打印1至100数字,expr用于运算逻辑
    • 3.While循环求1-100的总和
    • 4. 让用户在10s中内输入ip地址,并判断IP是否符合规范
    • 5. 每10秒钟判断mufengrow是否登录系统
    • 6. 猜数字游戏
    • 7. 问答游戏
  • 拓展 :shell脚本中表示递增有几种写法
  • 总结

while循环的介绍

While循环语句与for循环功能类似,主要用于对某个数据域进行循环读取、对文件进行遍历,通常用于需要循环某个文件或者列表,满足循环条件会一直循环,不满足则退出循环,其语法格式以while…do开头,done结尾。

while支持条件测试语句
整数比对
字符串比对
正则比对
文件比对

while读入文件的方式比较的特殊
while读入文件按行读取 IFS指定分隔符
for读入文件按空格读取 IFS指定分隔符

举例:

while read  file
do
        echo $file
done < /etc/passwd

while的语法结构

语法格式一:
while [条件]
do
        操作
done

语法格式二:
while read line
do
        操作
done  <  file

通过read命令每次读取一行文件,文件内容有多少行,while循环多少次

案例实战

1.循环打印企业官网,read指令用于读取行或者读取变量

#!/bin/bash
#2022年12月8日
#auto print company-web
#By author 沐风晓月
while read line
do 
echo $line
done < company.txt

其中company.txt内容为:
www.baidu.com
www.taobao.com
www.qq.com

2. 实现循环打印1至100数字,expr用于运算逻辑

#!/bin/bash

counter=1

while [ $counter -le 100 ]
do
    echo $counter
    counter=`expr $counter + 1`
done

expr 进行递增操作 counter = counter + 1

3.While循环求1-100的总和

#!/bin/bash

counter=1
sum=0

while [ $counter -le 100 ]
do
    sum=$(expr $sum + $counter)
    counter=$(expr $counter + 1)
done

echo "总和为: $sum"

4. 让用户在10s中内输入ip地址,并判断IP是否符合规范

#!/bin/bash
# 作者:mufenggrow

read -p "请输入IP地址:" ip_address

# 定义IP地址正则表达式
ip_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"

# 获取当前时间戳
start_time=$(date +%s)
end_time=$((start_time + 10))

while true; do
    # 判断是否超过10秒
    current_time=$(date +%s)
    if ((current_time >= end_time)); then
        echo "输入超时!"
        break
    fi

    # 检查IP地址是否符合规范
    if [[ $ip_address =~ $ip_regex ]]; then
        echo "IP地址符合规范!"
        break
    else
        echo "IP地址不符合规范,请重新输入:"
        read -p "请输入IP地址:" ip_address
    fi
done

此脚本中:使用=~运算符将用户输入与正则表达式进行匹配
ip_regex="^([0-9]{1,3}\.){3}[0-9]{1,3}$"是一个用于验证IP地址格式的正则表达式。

让我们逐步解释这个表达式:

  • ^ 表示匹配字符串的开头。
  • ([0-9]{1,3}.){3} 是一个重复的子模式,用于匹配3个类似于"数字数字数字."的组合。其中 [0-9]{1,3} 表示匹配一个或多个长度为 1 到 3 的数字,. 表示匹配正好一个点号。
  • [0-9]{1,3} 表示匹配一个或多个长度为 1 到 3 的数字,这是用于匹配IP地址的最后一组数字。
  • $ 表示匹配字符串的结尾。

综上所述,整个正则表达式可以用于匹配符合标准IPv4地址格式的字符串。该格式要求IP地址由4个数字组成,每个数字的范围是 0 到 255,数字之间由点号分隔。
以下是一些符合IP地址格式的示例:

192.168.0.1
10.0.0.255
172.16.100.50

使用这个正则表达式,可以在Shell脚本中判断用户输入的IP地址是否符合规范。

5. 每10秒钟判断mufengrow是否登录系统

#!/bin/bash
# 作者:mufenggrow

while true; do
    # 使用who命令获取当前登录的用户信息
    logged_in_users=$(who | grep "mufenggrow")

    # 检查是否有mufenggrow用户登录
    if [ -n "$logged_in_users" ]; then
        echo "mufenggrow用户已登录系统!"
    else
        echo "mufenggrow用户未登录系统。"
    fi

    # 等待10秒
    sleep 10
done

6. 猜数字游戏

#!/bin/bash
# 作者:mufenggrow

# 生成一个1到100之间的随机数
secret_number=$((RANDOM % 100 + 1))

# 初始化游戏状态和猜测次数
game_over=false
guesses=0

echo "欢迎来到猜数游戏!"

while [ "$game_over" = false ]; do
    read -p "请猜一个1到100之间的数字:" guess
    ((guesses++))  # 猜测次数加1

    # 检查猜测与随机数的比较
    if ((guess == secret_number)); then
        echo "恭喜你,猜对了!你用了 $guesses 次猜测。"
        game_over=true
    elif ((guess < secret_number)); then
        echo "太小了,请再猜一次。"
    else
        echo "太大了,请再猜一次。"
    fi
done

7. 问答游戏

#!/bin/bash
# 作者:mufenggrow

# 定义问题和答案的关联数组
declare -A questions=(
  ["什么语言出现在猫的声音中?"]="喵喵"
  ["什么东西一次一半,永远都吃不完?"]="水"
  ["最大的国家是哪个国家?"]="俄罗斯"
)

# 初始化游戏状态和得分
game_over=false
score=0

echo "欢迎来到问答游戏!"

while [ "$game_over" = false ]; do
  # 随机选择一个问题
  question_index=$((RANDOM % ${#questions[@]}))
  question="${!questions[@]:$question_index:1}"
  answer="${questions[$question]}"

  echo "问题:$question"
  read -p "请输入你的答案:" user_answer

  # 检查答案是否正确
  if [ "$user_answer" = "$answer" ]; then
    echo "回答正确!"
    ((score++))  # 得分加1
  else
    echo "回答错误。正确答案是:$answer"
  fi

  # 检查是否还有未回答的问题
  if [ ${#questions[@]} -eq $score ]; then
    echo "恭喜你,回答完所有问题!你的得分是 $score 分。"
    game_over=true
  else
    echo "========================"
    read -p "继续游戏?(输入 q 退出,其他键继续):" continue_game
    if [ "$continue_game" = "q" ]; then
      echo "游戏结束。你的得分是 $score 分。"
      game_over=true
    fi
  fi
done

shell_255">拓展 :shell脚本中表示递增有几种写法

  1. 使用 let 命令:
counter=1
let counter=counter+1

这种方式使用 let 命令对变量 counter 进行递增操作。

  1. 使用双括号 (( )):
counter=1
(( counter++ ))

这种方式使用双括号 (()) 对变量 counter 进行递增操作,使用 ++ 表示递增。

  1. 使用 expr 命令:
counter=1
counter=$(expr $counter + 1)

这种方式使用 expr 命令进行算术运算,将结果赋值给变量 counter。

  1. 使用 $(( )):
counter=1
counter=$(( counter + 1 ))

这种方式使用 $(( )) 对变量 counter 进行递增操作,将结果赋值给 counter。

  1. 使用 +=:
counter=1
counter+=1

这种方式使用 += 对变量 counter 进行递增操作。

总结

以上就是今天的全部内容,主要讲解了while循环的使用,后期会介绍一些综合性的项目,我是沐风晓月,期待与你一起成长。


http://www.niftyadmin.cn/n/471710.html

相关文章

GPT快速分区

经过刚刚的“转换分区表类型为GUID格式”设置之后&#xff0c;现在分区的分区表类型已经是GPT格式了。我们设置想要分区的数目&#xff0c;例如我想要分两个区&#xff0c;点击自定选择2个分区&#xff0c;系统C盘分了80G&#xff0c;剩下空间留给了D盘。默认勾选“创建新ESP分…

【Leetcode -637.二叉树的层平均值 -671.二叉树中第二小的节点】

Leetcode Leetcode -637.二叉树的层平均值Leetcode -671.二叉树中第二小的节点 Leetcode -637.二叉树的层平均值 题目&#xff1a;给定一个非空二叉树的根节点 root , 以数组的形式返回每一层节点的平均值。与实际答案相差 10^(- 5) 以内的答案可以被接受。 示例 1&#xff1…

笔记软件对比表格

小小的《程序员修炼之道》&#xff0c;读一点多懂一点&#xff0c;觉得总是输入&#xff0c;缺乏归档和复盘。整理对比了一下决定用回CSDN&#xff0c;主要是发现它支持搜索了。 笔记软件对比 可全局搜索云版本控制公开容易编辑修改支持md需要翻墙github✅✅✅✅⍻&#xff08;…

Spring FrameWork从入门到NB -三级缓存解决循环依赖内幕 (二)

开始用上一篇文章讲到的Spring依赖注入的步骤&#xff0c;用两个例子来推导一下整个过程&#xff0c;举例子有助于了解真相。 先用一个最简单的例子&#xff1a;没有依赖的单例bean的创建。 推导过程是需要上一篇文章的步骤的&#xff0c;要参照步骤一步一步来。 无依赖的单…

C和指针(九)链表和指向指针的指针

链表 1&#xff0c;链表是包含数据的独立数据结构的集合&#xff0c;链表中每个节点通过指针连接在一起&#xff0c;通常节点是动态分配的。 1&#xff09;单链表中每个节点包含一个指向下一节点的指针&#xff0c;链表最后一个节点的指针为NULL。 2&#xff09;链表中的节点可…

idea maven 中模块显示灰色,依赖不加载

idea maven 中模块显示灰色&#xff0c;依赖刷新了几次都无法加载引入 后面发现是被MAVEN设置忽略了 去掉忽略文件然后reimport &#xff0c;就正常了

Java Web JDBC(1)23.6.25

JDBC 1&#xff0c;JDBC概述 在开发中我们使用的是java语言&#xff0c;那么势必要通过java语言操作数据库中的数据。这就是接下来要学习的JDBC。 1.1 JDBC概念 JDBC 就是使用Java语言操作关系型数据库的一套API 全称&#xff1a;( Java DataBase Connectivity ) Java 数据库…

new String()创建几个对象

String str1 "abc"; // 在常量池中当直接赋值时&#xff0c;字符串“abc”会被存储在常量池中&#xff0c;只有1份&#xff0c;此时的赋值操作等于是创建0个或1个对象。如果常量池中已经存在了“abc”&#xff0c;那么不会再创建对象&#xff0c;直接将引用赋值给s…