核心:Shell 脚本三大流程控制:分支判断(if‑elif‑else /case)、循环(for、while),用来改变脚本默认从上到下顺序执行的逻辑。
一、多分支判断:case 语句
适用场景:同一个变量,匹配一堆固定的值,做多选。 不适合做数值大于、小于、区间判断。
1. 基础语法
case 变量 in
模式1)
命令
;;
模式2)
命令
;;
*) #相当于else,匹配所有其他情况,放最后
默认命令
;;
esac #case倒过来,case语句结束标记
必记 3 个坑:
-
每个分支结尾必须写双分号;;,代表这个分支结束,否则会继续往下执行;
-
结束标记是
esac,不能写 fi(fi 是 if 的结束); -
|代表或者 ,写多个值:9|10|11),适合两位数; -
[3‑5]只能匹配单个字符,只能 1 位数字,不能匹配 10、11 这种两位数!
2. 执行逻辑
拿变量的值从上往下和模式对比:
-
匹配上某一个模式 → 执行里面代码,遇到
;;直接跳到esac,不再判断后面分支; -
全都不匹配 → 执行
*)里面的默认代码。
3. 什么时候用 case,什么时候用 if‑elif
表格
| 语句 | 擅长 | 不擅长 | ||
|---|---|---|---|---|
| case | 同一个变量,匹配固定枚举值(菜单选项、yes/no、脚本参数 start/stop/restart) | 数值区间、大小比较、多无关条件 | ||
| if‑elif | 万能判断 :大小、范围、文件判断、多条件 `&& | ` 组合 | 大量固定枚举时代码臃肿 |
简单记:看范围用 if;看固定选项用 case。

二、循环语句:重复执行代码块
循环三要素:①循环条件 ②循环体(do‑done 中间代码)③要有退出条件,防止死循环。
1.for 循环:已知循环次数
特点:把列表里每一个值依次赋值给变量,列表有多少个元素,就循环多少次。适合遍历列表、文件、数字序列。
语法:
for 变量 in 值列表
do
循环执行的命令
done
for 的 4 种取值列表写法
-
直接写值:
for i in morning noon afternoon,空格分割每一个元素; -
变量取值:先把一堆值存到变量,再循环;
-
命令结果取值:反引号
cat /etc/hosts,拿命令输出当作列表; -
数字序列:
-
{5..10}:5 到 10; -
seq 起始 步长 结束,seq -w可以补 0 输出两位数(01、02)。
-
for 循环适合:我提前大概知道要循环多少次、遍历一堆对象。
2.while 循环:条件成立就循环
特点:先判断条件,条件为真就执行循环体;条件为假立刻退出循环。不知道循环多少次的时候优先用 while。
语法:
while [ 条件测试 ]
do
循环体命令
done
⚠️重点:循环内部一定要修改条件变量,不然条件永远成立,造成死循环。
-
例:
var=10,循环内写var=$(expr $var -1),不断减小 var,直到$var -gt 0不成立,循环结束。 -
while true:条件永远为真,死循环;需要脚本内部用exit跳出循环(猜价格游戏案例)。、
对比 for 和 while
-
for:看重列表元素个数,遍历固定集合,次数由列表决定;
-
while:看重条件真假,满足就循环,适合交互式、猜游戏、不确定循环多少次。
三、补充配套小知识点
1.exit 命令
写在脚本里面,直接结束整个脚本 ,后面代码不再执行。 exit 0代表正常退出;exit 1代表异常退出;可以用$?查看上一条命令返回值。
2.echo 彩色输出
echo -e 开启转义识别,格式:
echo -e "\033[字背景;文字颜色m 文字 \033[0m"
\033[0m必须加,用来关闭颜色,防止后续输出也带颜色。 文字颜色 30‑37,背景颜色 40‑47。
四、整体梳理自己的做题思路(写脚本思考步骤)
-
需求是
做选择判断
:
-
如果是一个变量的多个固定选项 → 选 case;
-
注意
|处理多值,不要用[]处理两位数;结尾;;、esac、*); -
如果是区间、大小、文件、多条件 → 选 if‑elif‑else,结尾
fi;
-
-
需求是
重复做事情(循环)
:
-
有明确的列表 / 确定循环次数 → for;
-
根据条件真假来循环,不知道循环多少次(交互输入猜题)→ while;
-
while 切记:循环内部要改变条件,避免死循环,死循环用
exit跳出。
-
-
写完成检查:分支有没有写结束标记(fi /esac);循环有没有
done;case 每个分支有没有;;。
五、易混淆对照表
表格
| 语句 | 开始 | 结束 | 分支结束标记 |
|---|---|---|---|
| if‑elif‑else | if | fi | 无,靠 elif/else 分隔 |
| case | case | esac | 每个分支末尾写;; |
| for | for | done | do‑done 包裹循环体 |
| while | while | done | do‑done 包裹循环体 |
易错点总结:
case 结束是 esac,不是 fi;if 结束才是 fi;
case 的[]只能匹配单个字符,不要拿来匹配 10、11;
while 循环一定要修改条件,不然死循环;
for 循环次数由 in 后面列表元素数量决定。