循环与case多分支
循环 && case多分支
[TOC]
初识while
while 属于循环语句,条件为真时反复执行循环体
while 条件do 命令集done# 条件满足就一直循环,直到条件不满足或遇到break/exit才退出==while true== 表示死循环,必须配合 break 或 exit 来退出,否则永远不会停止
break跳出循环
break 用于跳出当前层循环,break N 跳 N 层
✅️ break N中的N表示跳出的循环层数,默认 break = break 1
1)break跳出一层[root@shell ~]#cat while.sh#!/bin/bashwhile truedo echo 1... while true do echo 2... sleep 1 break # 跳出内层while donedone# break默认只跳一层,外层while继续执行'外层循环会不断进入内层→内层break→外层再进入内层...'# 效果: 1...2...1...2...1...2... 无限循环
2)break 2 跳出两层[root@shell ~]#cat while.sh#!/bin/bashwhile truedo echo 1... while true do echo 2... sleep 1 break 2 # 跳出2层循环 donedoneecho done............
[root@shell ~]#sh while.sh1...2...done............# break 2一次性跳出两层,直接到最外层done后面'break 2 让程序干净利落地收工'✅️ break → 跳出当前循环体,回到上一层 ✅️ exit → 终止整个脚本进程,不管嵌套多深
📌 关键区分:break 跳出循环,exit 退出脚本
猜数字游戏
RANDOM 随机数
RANDOM 是 bash 内置变量,生成 0-32767 之间的随机整数
1)生成1-100的随机数[root@shell ~]#echo $((RANDOM))17937# RANDOM范围是0-32767[root@shell ~]# echo $((RANDOM))27566[root@shell ~]#echo $((RANDOM%100+1))86# %100取余得到0~99,+1得到1~100'$((RANDOM%N+M)) 生成M到M+N-1之间的随机整数'🌰 带计数器版
2)带计数器——统计猜了几次[root@shell ~]#cat ran.sh#!/bin/bashrun=$(($RANDOM%100+1)) # 先随机生成一个1-100的目标数
while true; do let i++ # 每次循环计数器+1 read -p "请输入你要猜的数字(1-100):" num
if [ "$num" -gt "$run" ]; then echo "猜大了~" elif [ "$num" -lt "$run" ]; then echo "猜小了~" else echo "总共猜了${i}次, 🎉恭喜你终于猜对了~" exit fidone# let i++ 整数运算,自增计数器,统计循环次数✅️ 猜对时打印累计次数# 三种分支:大了、小了、猜对了'猜对就exit退出,游戏结束'ping脚本
[root@shell ~]#cat ping.sh#!/bin/bashping -c2 -W2 $1 &>/dev/null# -c2: 只发2个包 -W2: 超时1秒if [ $? -eq 0 ];then echo $1 ✅ 在线.....else echo $1 ❌ 不在线...fi
[root@shell ~]# bash ping.sh www.baidu.comwww.baidu.com ✅ 在线.....[root@shell ~]# bash ping.sh wwwww.basifasdfasdf.comwwwww.basifasdfasdf.com ❌ 不在线...'ping -c2 -W2 控制发包数和超时,避免脚本卡住'case语句
📌 类似 if,是流程控制语句,用于多分支匹配
语法结构
case 变量 in # 变量来源: 直接传参、赋值传参、read接收、脚本定义 匹配序列1) 命令集 ;; 匹配序列2) 命令集 ;; 匹配序列3) 命令集 ;; *) echo "Usage: $0 参数1|参数2"esac# ) 匹配序列后跟右括号# ;; 每个分支结束必须双分号# *) 通配符,匹配所有其他情况,类似default# esac case的反写,结束标志 ⭕🌰 基础示例
[root@shell ~]#cat case.sh#!/bin/bashcase $1 in shell) echo shell......... ;; mysql) echo mysql......... ;; nginx) echo nginx........ ;; *) echo "Usage: $0 [shell|mysql|nginx]" # 这里用双引号括起来esac# $1是脚本的第一个参数,case根据参数值分发到对应分支'最简单的case——传什么参数就执行什么分支'案例1:系统信息查看脚本
case + while 实现交互式菜单,循环接收用户输入
1)系统信息查看菜单[root@shell ~]#cat case.sh#!/bin/bashmen(){ echo -e "\e[34m\t\t(1)查看内存\e[0m" echo -e "\e[34m\t\t(2)查看磁盘\e[0m" echo -e "\e[34m\t\t(3)查看负载\e[0m" echo -e "\e[34m\t\t(4)显示主菜单\e[0m" echo -e "\e[34m\t\t(exit)退出~\e[0m"}men# 先调用一次函数 --> 显示菜单
while truedo read -p "输入后~查看对应系统编号[(4)显示菜单]: " num case $num in 1) free -h ;; 2) df -h ;; 3) uptime ;; 4) men # 重新显示菜单 ;; exit) exit ;; *) echo "Usage: $0 [1|2|3|4]" esacdone# men()函数封装菜单显示,避免在循环里重复写echo# case根据用户输入执行对应命令,选4重显菜单'函数定义菜单→while死循环等待输入→case匹配执行'✅️ 经典组合: while + case + 函数💡 men() 函数封装菜单显示,定义一次,多处调用——这就是函数的意义
案例2:Nginx启动脚本
1)确认nginx路径[root@web ~]#which nginx/usr/sbin/nginx[root@web ~]#/usr/sbin/nginx # 启动[root@web ~]#/usr/sbin/nginx -s stop # 停止[root@web ~]#/usr/sbin/nginx -s reload # 重新加载[root@web ~]#/usr/sbin/nginx -s stop && sleep 1 && /usr/sbin/nginx # 重启# restart: 先stop,sleep 1秒等进程结束,再start✅ nginx通过-s参数控制: stop停止、reload重载、stop+sleep+start=重启========================================小bug🐛 --> 如果nginx处于停止状态,-s stop 会报错root@Ubuntu ~# nginx -s stoproot@Ubuntu ~# ss -lntup | grep nginx | wc -l0root@Ubuntu ~# /usr/sbin/nginx -s stop && sleep 1 && /usr/sbin/nginxnginx: [error] open() "/run/nginx.pid" failed (2: No such file or directory)# 本来就没有运行,没有办法关闭 ❌ --> 后面也Nginx也启动不起来~root@Ubuntu ~# ss -lntup | grep nginx | wc -l0'优化后'root@Ubuntu ~# /usr/sbin/nginx -s stop 2>/etc/null; sleep 1 && /usr/sbin/nginx# 吞掉报错 --> ;无论是否成功继续启动Nginxroot@Ubuntu ~# echo $?0 ✅ 说明上一条命令执行成功root@Ubuntu ~# ss -lntup | grep nginx | wc -l1 ✅ 服务启动成功========================================
2)Nginx启动脚本'加执行结果反馈(加成功/失败提示)'# 避免重复代码[root@web ~]#cat nginx.sh#!/bin/bashac=$1# 在函数外 $1 是脚本的第一个参数# 把$1先存到变量,方便函数内引用te(){ if [ $? -eq 0 ];then echo -e "\e[32m Nginx $ac 成功✅\e[0m" else echo -e "\e[31m Nginx $ac 失败❌\e[0m" fi}
case $ac in start) /usr/sbin/nginx te ;; stop) /usr/sbin/nginx -s stop te ;; reload) /usr/sbin/nginx -s reload te ;; restart) /usr/sbin/nginx -s stop 2>/etc/null; sleep 1 && /usr/sbin/nginx te ;; status) nginx_re=`ps axu|grep "nginx: master"|grep -v grep|wc -l` [ $nginx_re -eq 0 ] && echo "nginx未运行❌" || echo "Nginx运行中ing✅" # 通过过滤 nginx 的主进程,来判断nginx是否在运行 # 等于0,说明主进程没有启动起来~ # grep -v grep排除grep自身进程,不然统计会多1 ;; *) echo "Usage: $0 [start|stop|restart|reload|status]"esac# te()把重复的成功/失败判断封装起来,每个分支只需调用一行te✅️ 函数可以访问外部变量$ac——函数内外不是完全隔离的✅️ status分支逻辑不同,不需要TE,保持独立即可案例3:case或判断表达式
case 支持 | 匹配多个值
1)用if -o实现或判断[root@shell ~]#cat jumpserver.sh#!/bin/bashweb=10.0.0.7WEB02=10.0.0.8DB01=10.0.0.51men(){ echo -e "\e[34m\t\t\t\t\t1.web\e[0m" echo -e "\e[34m\t\t\t\t\t2.WEB02\e[0m" echo -e "\e[34m\t\t\t\t\t3.DB01\e[0m"}men
read -p "输入连接的服务器编号或者IP地址或者主机名称" numif [ $num = 1 -o $num = web -o $num = 10.0.0.7 ];then# 这里必须用的是字符串匹配,-eq只能用于整数# 如果输入的是 web -eq 1 会报错的~ echo hehefi# -o 表示or,多个条件有一个成立即可'if用-o写多个or条件,但多了可读性差'
========================================2)用case | 实现——更优雅========================================[root@shell ~]#cat jumpserver.sh# ...变量定义和men1函数同上...read -p "输入连接的服务器编号或者IP地址或者主机名称" numcase $num in 1|web|10.0.0.7) echo web........... ;; 2|WEB02|10.0.0.8) echo web02...... ;;esac# case中用|分隔多个匹配值,比if -o直观太多✅️ case + | 是写多条件匹配的首选方式案例4:跳板机脚本
1)基础跳板机[root@shell ~]#cat jumpserver.sh#!/bin/bashweb=172.16.1.7WEB02=172.16.1.8DB01=172.16.1.51men1(){ echo -e "\e[34m\t\t\t\t\t1.web\e[0m" echo -e "\e[34m\t\t\t\t\t2.WEB02\e[0m" echo -e "\e[34m\t\t\t\t\t3.DB01\e[0m"}men1
read -p "输入连接的服务器编号或者IP地址或者主机名称" numcase $num in 1|web) ssh $web ;; 2|WEB02) ssh $WEB02 ;;esac
========================================2)免密登录准备——先和客户端做免密钥========================================[root@shell ~]#ssh-keygen # 服务端生成密钥对[root@shell ~]#ssh-copy-id 172.16.1.8[root@shell ~]#ssh-copy-id 172.16.1.7# 免密后ssh直接连,不弹密码框完善版跳板机——角色+密码+验证码
1)完善后的jumpserver[root@shell ~]#cat jumpserver.sh#!/bin/bashweb=172.16.1.7WEB02=172.16.1.8DB01=172.16.1.51role(){ echo -e "\e[33m\t\t\t\t\t1.运维\e[0m" echo -e "\e[33m\t\t\t\t\t2.开发\e[0m"}role
men1(){ echo -e "\e[34m\t\t\t\t\t1.web\e[0m" echo -e "\e[34m\t\t\t\t\t2.WEB02\e[0m" echo -e "\e[34m\t\t\t\t\t3.DB01\e[0m"}
men2(){ echo -e "\e[34m\t\t\t\t\t1.web\e[0m"}
trap "" HUP TSTP INT# 屏蔽Ctrl+C等信号,防止用户退出脚本
read -p "请输入你的角色: " numif [ $num -eq 1 ];then # 运维——可管理所有主机 while true do read -p "请输入你的密码: " pass if [ $pass -eq 123 ];then break else let i++ echo "你输入密码不正确、请重新输入" [ $i -eq 3 ] && echo 密码错误次数过多,请稍后再试 && sleep 5 if [ $i -eq 5 ];then read -p "密码次数过多请输入你的微信账号: " wx ran=`echo $((RANDOM))|md5sum|cut -c 1-8` echo 验证码已发送到$wx python2.7 weixin.py "$wx" "验证码" "$ran" read -p "请输入接收到的验证码: " ra if [ $ra = $ran ];then python2.7 weixin.py "$wx" "密码" "123" unset i continue else echo hehe fi fi fi done men1 while true do read -p "输入连接的服务器编号[p输出主机列表]: " num case $num in 1|web) ssh $web ;; 2|WEB02) ssh $WEB02 ;; p) men1 ;; esac doneelif [ $num -eq 2 ];then # 开发——只能连web men2 while true do read -p "输入连接的服务器编号[p输出主机列表]: " num case $num in 1) ssh $web ;; p) men2 ;; esac donefi# 运维角色:输密码→最多3次重试→5次锁住→微信验证码解锁→显示运维菜单# 开发角色:直接显示开发菜单,只能连web'用角色控制权限——运维看全菜单,开发只看一台机器'⚠️ trap屏蔽信号防止Ctrl+C退出,要预留后门: woshiyunwei→exit📌 跳板机核心设计:
- ① 角色分离——运维 vs 开发,菜单不同
- ② 密码验证——3次错误锁5秒,5次错误发微信验证码
- ③ trap 屏蔽信号——防止 Ctrl+C 直接退出
- ④ 预留后门——
woshiyunwei)→exit
for循环
语法结构
for i in 取值列表do 命令集合done# i 是循环变量,每次从取值列表中取一个值# 取值列表可以是: 字符串、数字、序列、命令、变量案例1:循环数字
1)直接写数字列表[root@shell ~]#cat for.shfor i in 1 2 10do echo $idone[root@shell ~]#sh for.sh1210# 数字以空格分隔,for按空格取值案例2:循环字符串
2)循环字符串[root@shell ~]#cat for.shfor i in a b cdo echo $idone[root@shell ~]#sh for.shabc# 字符串同样按空格分隔案例3:支持序列
3)数字序列 {1..10}[root@shell ~]#cat for.shfor i in {1..10}do echo $idone[root@shell ~]#sh for.sh12345678910# {1..10} 自动展开为1到10的序列
========================================4)字母序列 {a..d}========================================[root@shell ~]#cat for.shfor i in {a..d}do echo $idone[root@shell ~]#sh for.shabcd'{a..d} 字母序列也能展开,好用'案例4:支持命令
取值列表可以来自命令的输出——用反引号 ` 或 $() 包裹
5)seq命令生成序列[root@shell ~]#cat for.shread -p "请输入数字: " numfor i in `seq $num`do echo $idone[root@shell ~]#sh for.sh请输入数字: 512345# seq $num 动态生成1到$num的序列
========================================6)cat命令读取文件========================================[root@shell ~]#cat for.shfor i in `cat 1.txt`do echo $idone[root@shell ~]#cat 1.txtzhangsanlisi[root@shell ~]#sh for.shzhangsanlisi# cat 1.txt的输出作为取值列表'命令结果也能当列表——for的取值来源非常灵活'案例5:支持拼接
7)变量拼接[root@shell ~]#cat for.shfor i in {1..3}do echo a$idone[root@shell ~]#sh for.sha1a2a3# 循环体内可以用变量$i做各种拼接案例6:批量创建用户
8)批量创建用户——基础版[root@shell ~]#cat for.shfor i in {1..3}do useradd oldboy$idone# 循环三次,创建oldboy1、oldboy2、oldboy3
========================================9)批量创建用户——灵活版(输入前缀和个数)========================================[root@shell ~]#cat for.shread -p "请输入用户前缀: " prefixread -p "请输入用户个数: " numfor i in `seq $num`do user=$prefix$i echo $userdone
read -p "[y创建用户|d删除用户]" num1for a in `seq $num`do case $num1 in y) user=$prefix$a id $user &>/dev/null if [ $? -eq 0 ];then echo "$user 用户已存在" else useradd $user &>/dev/null [ $? -eq 0 ] && echo $user创建成功 fi ;; d) user=$prefix$a id $user &>/dev/null if [ $? -eq 0 ];then userdel -r $user [ $? -eq 0 ] && echo $user删除成功 else echo "$user 用户不存在" fi ;; esacdone# 先输入前缀和个数预览用户名,再选择y创建或d删除'id检查用户是否存在→存在跳过/不存在创建'✅️ 创建前先预览,确认后再操作——安全操作的好习惯案例7:批量探测IP是否在线
笔试题经典:探测 10.0.0.1-254 的 IP 地址是否在线
1)并发ping探测[root@shell ~]#cat ping.sh#!/bin/bashfor i in `seq 254`do { ip=10.0.0.$i ping -c1 -W1 $ip &>/dev/null if [ $? -eq 0 ];then echo $ip 在线... fi } &donewaitecho 探测完成.....# {} & 每个ping放进后台并发执行,254个同时跑# wait 等待所有后台进程结束后再继续'不用{}&,254个IP顺序ping要等很久——并发才是王道'✅️ 后台并发 + wait等待 = 快速批量ping案例8:从文件读取创建用户
2)从文件批量创建用户[root@shell ~]#cat user.sh#!/bin/bashfor i in `cat 1.txt`do useradd $idone
[root@shell ~]#cat 1.txtzhangsanlisilaowang# 用户列表写在文件里,for循环逐行读取创建案例9:给每个用户设置随机密码
3)创建用户并设随机密码[root@shell ~]#cat for.shread -p "请输入用户前缀: " prefixread -p "请输入用户个数: " numfor i in `seq $num`do user=$prefix$i echo $userdone
read -p "[y创建用户|d删除用户]" num1for a in `seq $num`do case $num1 in y) user=$prefix$a id $user &>/dev/null if [ $? -eq 0 ];then echo "$user 用户已存在" else useradd $user &>/dev/null [ $? -eq 0 ] && echo $user创建成功 echo $user >> pass.txt echo `mkpasswd`|tee -a pass.txt|passwd --stdin $user fi ;; d) user=$prefix$a id $user &>/dev/null if [ $? -eq 0 ];then userdel -r $user [ $? -eq 0 ] && echo $user删除成功 else echo "$user 用户不存在" fi ;; esacdone# mkpasswd生成随机密码串→tee记录到pass.txt→passwd --stdin设给用户'mkpasswd生成随机密码,tee一边记密码本一边设密码'✅️ 密码记录到pass.txt方便后续分发🤡 生产环境记得保管好 pass.txt,或者用完就删
命令行一行for
# 命令行快速循环——适合临时批量操作[root@shell ~]#for i in `seq 5`;do echo $i;done12345
[root@shell ~]#for i in `seq 5`;do echo old$i;doneold1old2old3old4old5
# 批量建用户——一行搞定[root@shell ~]#for i in `seq 5`;do useradd old$i;done[root@shell ~]#tail -5 /etc/passwdold1:x:1014:1014::/home/old1:/bin/bashold2:x:1015:1015::/home/old2:/bin/bashold3:x:1016:1016::/home/old3:/bin/bashold4:x:1017:1017::/home/old4:/bin/bashold5:x:1018:1018::/home/old5:/bin/bash
# 批量删——也是一行[root@shell ~]#for i in `seq 5`;do userdel -r old$i;done# 命令行for循环是运维的瑞士军刀'一行建5个,一行删5个——简洁高效'案例10:100内能被3整除的数的和
1)执行过程分析for i in `seq 100`# i=1: 1%3=1 不等于0 跳过# i=2: 2%3=2 不等于0 跳过# i=3: 3%3=0 count=$[0+3]=3# i=4: 4%3=1 不等于0 跳过# i=5: 5%3=2 不等于0 跳过# i=6: 6%3=0 count=$[3+6]=9# ...以此类推...
========================================2)完整脚本========================================[root@shell ~]#cat count.sh#!/bin/bashfor i in `seq 100`do num=`echo $[$i%3]` # $i%3 取余数 if [ $num -eq 0 ];then count=$[$count+$i] # 余数为0则累加 fidoneecho $count[root@shell ~]#sh count.sh1683# 100以内能被3整除的数: 3,6,9,...,99 总和1683案例11:for循环从1加到100
[root@shell ~]#cat c.shfor i in `seq 100`do count=$[count+i]doneecho $count[root@shell ~]#sh c.sh5050# 经典的累加——for循环的最佳练手题while循环
语法结构
while [ 条件表达式 ] # 成立则执行、不成立不执行do 命令集合done📌 和 if 一样用 [ ] 条件表达式,条件成立才进入循环体
案例1:死循环的两种写法
1)while truewhile truedo echo hehedone# true永远为真→死循环
========================================2)while [ 条件恒成立 ]========================================while [ 10 -eq 10 ]do echo hehedone# 10永远等于10→也是死循环'两种写法等效,while true更常用'案例2:循环序列(while版)
1)while实现1到100[root@shell ~]#cat while.sh#!/bin/bashi=1while [ $i -le 100 ]do echo $i let i++done# while版需要自己维护计数器:初始值i=1,每次let i++,条件i<=100'while不像for自动取序列——需要手动管理变量和条件'案例3:从1加到100(while版)
[root@shell ~]#cat while.sh#!/bin/bashi=1while [ $i -le 100 ]do c=$[c+i] let i++doneecho $c[root@shell ~]#sh while.sh5050# 同样的累加逻辑,while版三步:初始化i→循环累加→自增案例4:for vs while 读取文件的关键区别
1)准备测试文件[root@shell ~]#cat /etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6# /etc/hosts每行有多个字段,空格分隔
========================================2)for循环——按空格分隔========================================[root@shell ~]#cat while.sh#!/bin/bashfor i in `cat /etc/hosts`do echo $idone[root@shell ~]#sh while.sh127.0.0.1localhostlocalhost.localdomainlocalhost4localhost4.localdomain4::1localhostlocalhost.localdomainlocalhost6localhost6.localdomain6# for按空格和换行符切分,每个词单独一行'for循环:见到空格就切一刀——不管原来是不是一行'
========================================3)while read——按行读取========================================[root@shell ~]#cat while.sh#!/bin/bashwhile read linedo echo $linedone</etc/hosts[root@shell ~]#sh while.sh127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4::1 localhost localhost.localdomain localhost6 localhost6.localdomain6# while read 逐行读取,保留每行的原始格式'while read:一行就是一整行——空格不动'📌 核心区别:for 按空格分隔值,while read 按行读取——读文件内容时 while read 更准确
案例5:基于文件批量创建用户和密码
1)准备用户密码文件[root@shell ~]#cat 1.txtzhangsan test.oldboy123.comlisi old.123.comlaowang hehe.123.com# 每行:用户名 密码
========================================2)while read 逐行处理========================================[root@shell ~]#cat while.sh#!/bin/bashwhile read linedo user=`echo $line|awk '{print $1}'` pass=`echo $line|awk '{print $2}'`
useradd $user &>/dev/null [ $? -eq 0 ] && echo $user 创建成功 echo $pass|passwd --stdin $userdone<1.txt# read读每一行→awk取第1列用户名、第2列密码→创建用户并设密码'done < 1.txt 把文件重定向到while循环的标准输入'✅️ while read + awk 是处理格式化文件的经典组合流程控制:break continue exit
1)exit——直接退出脚本========================================[root@shell ~]#useradd old3# 先让old3存在,触发exit分支[root@shell ~]#cat while.sh#!/bin/bashfor i in {1..5}do user=old$i id $user &>/dev/null if [ $? -eq 0 ];then exit # 直接退出脚本 else useradd $user &>/dev/null [ $? -eq 0 ] && echo $user创建成功 fidoneecho 执行完成.......[root@shell ~]#sh while.shold1创建成功old2创建成功# old3已存在→触发exit→脚本直接终止→最后的echo没执行'exit是核武器——不管在哪层,直接结束整个进程'
========================================2)break——跳出循环继续执行========================================[root@shell ~]#for i in `seq 2`;do userdel -r old$i;done# 清理old1和old2[root@shell ~]#cat while.sh#!/bin/bashfor i in {1..5}do user=old$i id $user &>/dev/null if [ $? -eq 0 ];then break # 跳出循环继续执行 else useradd $user &>/dev/null [ $? -eq 0 ] && echo $user创建成功 fidoneecho 执行完成.......[root@shell ~]#sh while.shold1创建成功old2创建成功执行完成.......# old3已存在→触发break→跳出for循环→继续执行echo'break是退出当前循环——脚本还活着,echo照常执行'
========================================3)continue——跳过本次,继续下一次========================================[root@shell ~]#for i in `seq 2`;do userdel -r old$i;done[root@shell ~]#sh while.shold1创建成功old2创建成功old4创建成功old5创建成功执行完成.......# old3存在→触发continue→跳过old3的创建→继续old4、old5'continue是跳过当前这一轮——下一轮照常跑'# old3被跳过了,但old4和old5正常创建| 命令 | 作用 | 影响范围 |
|---|---|---|
exit | 直接终止整个脚本 | 整个进程 |
break | 跳出当前循环体 | 当前循环 |
continue | 跳过本次循环,继续下一次 | 当前循环的本次迭代 |
项目练习
① 写过的项目都需要加上判断:
- 判断传参不能为空
- 判断必须为整数
- 判断必须连续的字符串
② 中午吃啥?随机生成一个——用 RANDOM + case 实现
③ 老男孩大饭店——二级菜单 + 会员系统 + 结账
④ 大酒店服务——菜单 + 服务 + 价格 + 会员 + 消费 + 余额
⑤ 双色球——随机数生成 + 数组统计
📌 这些项目将 while + case + for + 函数 + 数组综合运用,是检验学习成果的好练习
小结
| 知识点 | 核心要点 |
|---|---|
while | 条件循环,while true = 死循环,配合 break / exit 退出 |
break N | 跳出 N 层循环,默认 = break 1 |
exit | 直接退出整个脚本,不管嵌套多深 |
continue | 跳过本次循环,继续下一次 |
case | 多分支匹配,| 连接多值,;; 结束分支,*) 通配,esac 结束 |
for i in 列表 | 取值列表支持:字符串、数字、{1..10} 序列、`命令`、变量 |
for vs while read | for 按空格分隔,while read 按行读取 |
{} & + wait | 后台并发 + 等待所有结束——批量任务加速 |
let i++ | 整数自增,等效 ((i++)),常用于计数器 |
RANDOM | bash 内置随机数,范围 0-32767,$((RANDOM%100+1)) 生成 1-100 |
$? | 上一条命令返回值,0 = 成功,非0 = 失败 |
trap "" HUP TSTP INT | 屏蔽信号,防止 Ctrl+C 退出脚本 |
/etc/init.d/functions | 系统函数库,action 美化输出 [ OK ] / [FAILED] |
📌 三种循环各自适用场景:
for—— 知道循环次数 / 遍历列表 / 批量操作while—— 条件判断式循环 / 逐行读文件 / 死循环+breakcase—— 多分支分发 / 服务管理脚本 / 菜单路由
📌 代码进化思路:基础实现 → 加状态反馈 → 抽函数去冗余 → 用系统库美化
文章分享
如果这篇文章对你有帮助,欢迎分享给更多人!




