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

Shell循环语句---for和while

目录

一.循环语句

1.1 定义

1.2 循环语句的执行过程

1.3 循环语句的分类

二.for循环语句

 2.1 语句格式

2.1.1 带列表循环的格式

2.1.2 不带列表循环的格式(不常用)

2.1.3类C循环 

​编辑

2.2 for循环语句相关练习 

 2.2.1求出1-100中所有奇数的和

 2.2.2 九九乘法表 输出九九乘法表

 2.2.3批量修改文件后缀

 2.2.4 批量创建指定用户,并添加用户密码

 2.2.5 查看某网段下所有主机的状态并导入指定文件中 

三.while循环语句

3.1语句格式

3.2 语句执行过程

3.3while循环语句相关练习

3.3.1 1-100求和

3.3.2 猜价格游戏 

 3.3.3 批量添加用户

四.break continue和exit区别 


一.循环语句

1.1 定义

循环语句是编程中用于重复执行特定代码块的控制结构,它根据条件或迭代规则自动重复操作,直到满足终止条件为止,循环的核心作用是减少重复代码。

1.2 循环语句的执行过程

1.3 循环语句的分类

根据是否预先知道循环次数分类:

  • 循环次数事先已知: for 

  • 循环次数事先未知: while 和 until 

因为until比较少用,所以重点介绍for和while 

二.for循环语句

 2.1 语句格式

for循环语句格式可以分为以下三类:

  • 列表循环

  • 不带列表循环

  • 类C风格的for循环

2.1.1 带列表循环的格式

for 变量名 in   {list}   #变量名通常是i,因为i是标准格式
docommand              #循环动作
done

示例:求1-50的奇数和

#!/bin/bashsum=0
for num in $(seq 1 2 50);            # seq 1 2 50 生成 1,3,5,...,49
do                         sum=$((sum + num))
done
echo "1-50的奇数和为: $sum"

补充:

seq [选项] 起始值 [步长] 结束值seq 5      # 输出:1 2 3 4 5
seq 3 6    # 输出:3 4 5 6
seq 1 2 9  # 输出:1 3 5 7 9(步长=2)

注意:

$( )和$(( ))的共同点

都会有返回输出

不同点

$( ) → 用于执行命令(如 $(ls))。

$(( )) → 用于数学计算(如 $((1 + 2)))。

 运作结果如下:

2.1.2 不带列表循环的格式(不常用)

for 变量名 
docommand
done

示例:打印hello

#!/bin/bash
for i    
doecho hello
done

运行结果如下 

2.1.3类C循环 

定义:在 Shell 脚本中,"类C循环"(C-style for loop)指的是语法类似于 C/C++/Java 语言的 for 循环,采用三表达式结构:

for ((初始化; 条件判断; 变量更新)); 
do# 循环体
done

示例:求1-10内奇数和 

#!/bin/bash
for ((i=1;i<=10;i+=2))   
dosum=$[i+sum]
done
echo $sum

结构如下

2.2 for循环语句相关练习 

2.2.1求出1-100中所有奇数的和

#!/bin/bashsum=0
for i in $(seq 1 100); 
do((sum += i))  
done
echo "1-100的和为: $sum"

 2.2.2 九九乘法表 输出九九乘法表

#!/bin/bashfor j in {1..9}        #外层循环,j从1到9,表示乘法表的行
dofor i in `seq $j`  #内层循环,i从1到当前j的值,表示每行的列do#打印乘法公式和结果,echo -e表示启用转义字符的解释,使用\t制表符对齐,\c表示不换行echo -e "${i}*${j}=`echo $[i*j]`\t\c"                                                doneecho  #每行结束后换行
done

运行结果如下

 2.2.3批量修改文件后缀

#!/bin/bash
cd 目标目录 || exit 1  # 如果目录不存在则退出for i in *; do# 提取字母部分(去掉数字)alpha=$(echo "$i" | awk -F '[0-9]+' '{print $1}')# 提取第一个连续数字串alnum=$(echo "$i" | grep -oE '[0-9]+' | head -n 1)# 如果没有数字,则保持原名(或自定义处理)if [ -z "$alnum" ]; thenecho "跳过文件(无数字): $i"continuefi# 执行重命名(先打印测试,确认无误后再真正执行)echo "mv \"$i\" \"${alnum}${alpha}.aa\""# mv "$i" "${alnum}${alpha}.aa"  # 去掉注释以真正执行
done

 

 

 

 

 

再次运行脚本即可

查看是否修改成功

 

 

 2.2.4 批量创建指定用户,并添加用户密码

​
#!/bin/bash# 检查 user.txt 是否存在
if [ ! -f "./user.txt" ]; thenecho "错误:user.txt 不存在,请先创建并填写用户名(每行一个)"exit 1
fi# 遍历 user.txt,创建用户并设置密码(123456)
for username in $(cat ./user.txt); do# 跳过空行[ -z "$username" ] && continue# 检查用户是否存在,不存在则创建if ! id "$username" &>/dev/null; thenuseradd "$username" && echo "用户 $username 创建成功"&>/dev/nullelseecho "用户 $username 已存在,跳过创建"fi# 设置密码(123456)echo "123456" | passwd --stdin "$username" &>/dev/null && echo "密码设置成功"
doneecho "所有用户创建及密码设置完成!"​

创建过程

1.创建 user.txt,每行一个用户名:
echo -e "user1\nuser2\nuser3" > user.txt

2.赋予脚本执行权限:
chmod +x user.sh

3.运行脚本:
./user.sh

2.2.5 查看某网段下所有主机的状态并导入指定文件中 

for i in {1..254}; do{ping -c2 -W1 192.168.52.$i &>/dev/nullif [ $? -eq 0 ]; thenecho "192.168.52.$i is online" >> online.txtelseecho "192.168.52.$i is offline" >> offline.txtfi} &#254个并发Ping可能对网络造成压力,控制并发数(最多20个并行进程)if (( $(jobs -p | wc -l) >= 20 )); thenwait -nfi
done
wait  #等待所有后台任务完成

注意:wait -n在某些较旧的Bash版本可能不支持

可以通过升级Bash来解决

# 更新所有包(包括bash)
sudo yum update -y# 或者单独更新bash
sudo yum update bash -y

三.while循环语句

 3.1语句格式

while  判断条件
docommand
done 

3.2 语句执行过程

 

 while循环一般用于有条件判断的循环,若判断条件为真,则进入循环,当条件为假就跳出循环

3.3while循环语句相关练习

3.3.1 1-100求和

#!/bin/bash
i=0
sum=0
while [ $i -le 100 ]
do
let sum+=$i
#防止死循环
let i++ 
done
echo $sum

3.3.2 猜价格游戏 

​
​
#!/bin/bash# 生成 1-1000 的随机价格
price=$((RANDOM % 1000 + 1))
attempts=0echo "欢迎参加猜价格游戏!价格范围是 1-1000。"while true; doread -p "请输入您的猜测: " guess((attempts++))if [[ ! "$guess" =~ ^[0-9]+$ ]]; thenecho "错误:请输入数字!"continuefiif (( guess == price )); thenecho "恭喜!正确价格是 $price。您猜了 $attempts 次。"exit 0elif (( guess > price )); thenecho "太高了!"elseecho "太低了!"fi
done​​

须知: 

[[ 字符串 =~ 正则表达式 ]]

  • 如果 字符串 符合 正则表达式,条件返回 true(退出状态码 0)。

  • 否则返回 false(退出状态码 1)。

[[ ! "$guess" =~ ^[0-9]+$ ]]

作用:检查用户输入 $guess 是否是一个 纯数字。

正则表达式分解:

  • ^:匹配字符串开头。

  • [0-9]:匹配任意数字(0-9)。

  • +:匹配前面的字符(数字)至少一次。

  • $:匹配字符串结尾。

 3.3.3 批量添加用户

#!/bin/bash# 检查 root 权限
if [ "$(id -u)" -ne 0 ]; thenecho "错误:请使用 root 用户运行此脚本!" >&2exit 1
fi# 批量创建用户并设置密码
for i in {1..20}; dousername="stu${i}"# 检查用户是否已存在if id "${username}" &>/dev/null; thenecho "用户 ${username} 已存在,跳过创建"continuefi# 创建用户if useradd "${username}"; then# 设置密码(兼容所有 Linux)echo "${username}:123123" | chpasswd# 强制用户首次登录修改密码(可选)passwd -e "${username}" &>/dev/nullecho "用户 ${username} 创建成功,密码已设置为 123123"elseecho "错误:用户 ${username} 创建失败!" >&2fi
done

四.break continue和exit区别 

  • break跳出单个循环 break n 数字数字是几代表跳出n层循环

  • continue终止某次循环中的命令,但是不会完全终止命令

  • exit 直接退出脚本

相关文章:

  • 【上海大学数据库原理实验报告】MySQL数据库的C/S模式部署
  • 发送百度地图的定位
  • 物联网蓬勃发展是助力楼宇自控技术迈向成熟的关键
  • AI 健康小屋:开启智慧健康管理新范式
  • # 06_Elastic Stack 从入门到实践(六)
  • ffmpeg av_buffer_unref的逻辑实现; av_freep 和 av_freep函数的区别
  • 用c语言实现——一个带头节点的链队列,支持用户输入交互界面、初始化、入队、出队、查找、判空判满、显示队列、遍历计算长度等功能
  • 神经网络权重优化秘籍:梯度下降法全解析(五)
  • 记录一次使用面向对象的C语言封装步进电机驱动
  • Shell脚本中的字符串截取和规则变化
  • 深度学习基石:神经网络核心知识全解析(一)
  • 运行neo4j.bat console 报错无法识别为脚本,PowerShell 教程:查看语言模式并通过注册表修改受限模式
  • 【Java面试笔记:基础】5.String、StringBuffer、StringBuilder有什么区别?
  • transformer 子层连接结构
  • 迅为iTOP-RK3576开发板/核心板6TOPS超强算力NPU适用于ARM PC、边缘计算、个人移动互联网设备及其他多媒体产品
  • ElasticSearch深入解析(一):Elastic Stack全景
  • Java实例化对象都有几种方式
  • (undone) 吴恩达版提示词工程 3. 迭代 (建议用到的时候再根据目录针对看)
  • 学习笔记——《Java面向对象程序设计》-继承
  • PyTorch DDP 跨节点通信的底层机制
  • 什么是中国好手艺?材美、工巧、器韵、时宜
  • ESG领跑者|每一步都向前,李宁要让可持续发展成为可持续之事
  • 宇树的任务已经完成?王兴兴也在等待行业拐点
  • 美团回应京东“二选一”指控:没有任何理由对某平台进行任何限制
  • 最高法:抢票软件为用户提供不正当优势,构成不正当竞争
  • 世界史圆桌|16-18世纪的跨太平洋贸易