Shell 流程控制(手把手讲解)
💡一则或许对你有用的小广告
欢迎加入小哈的星球 ,你将获得:专属的项目实战(已更新的所有项目都能学习) / 1v1 提问 / Java 学习路线 / 学习打卡 / 每月赠书 / 社群讨论
- 新开坑项目:《Spring AI 项目实战》 正在持续爆肝中,基于 Spring AI + Spring Boot 3.x + JDK 21..., 点击查看 ;
- 《从零手撸:仿小红书(微服务架构)》 已完结,基于
Spring Cloud Alibaba + Spring Boot 3.x + JDK 17...
,点击查看项目介绍 ;演示链接: http://116.62.199.48:7070 ;- 《从零手撸:前后端分离博客项目(全栈开发)》 2 期已完结,演示链接: http://116.62.199.48/ ;
截止目前, 星球 内专栏累计输出 90w+ 字,讲解图 3441+ 张,还在持续爆肝中.. 后续还会上新更多项目,目标是将 Java 领域典型的项目都整一波,如秒杀系统, 在线商城, IM 即时通讯,权限管理,Spring Cloud Alibaba 微服务等等,已有 3100+ 小伙伴加入学习 ,欢迎点击围观
在 Shell 脚本编程中,流程控制是实现自动化任务的核心工具。它允许开发者通过条件判断、循环结构和函数调用等方式,让脚本根据实际情况动态调整执行路径。无论是检查文件是否存在、批量处理数据,还是构建复杂的系统管理工具,掌握 Shell 流程控制都是提升脚本效率和灵活性的关键。本文将从基础语法到实战案例,逐步解析这一主题,帮助读者建立系统化的理解。
一、流程控制的基础语法
1.1 条件判断:分支逻辑的起点
Shell 脚本的条件判断主要通过 if
语句实现,其核心逻辑类似于生活中的“如果…那么…”决策模式。例如,判断一个文件是否存在,若存在则输出提示信息,否则执行其他操作。
if [ -f "/path/to/file.txt" ]; then
echo "文件存在,准备处理..."
else
echo "文件不存在,请检查路径!"
fi
这里 [ ]
是 test
命令的简写形式,用于执行条件表达式。常见的测试运算符包括:
-f
:检查文件是否为普通文件-d
:检查是否为目录-n
:判断字符串长度是否非零==
:比较字符串是否相等
比喻:可以把 if
语句想象成交通信号灯——当条件(红灯)满足时,执行对应的操作(停车);否则继续执行其他逻辑(绿灯通行)。
1.2 简化条件表达式:[[ ]]
的优势
在较新的 Shell 版本(如 Bash 4.x+)中,[[ ]]
替代了 [ ]
,提供了更强大的功能:
- 支持通配符(如
[[ $var == *.txt ]]
) - 自动忽略空格(无需转义)
- 支持逻辑运算符
&&
和||
if [[ -f "/path/to/file.txt" && -n "$VAR" ]]; then
echo "文件存在且变量非空,继续执行!"
fi
二、条件判断的进阶:多分支与模式匹配
2.1 elif
的分层决策
当需要处理多个条件分支时,elif
(else if 的缩写)可以构建阶梯式判断逻辑。例如,根据用户输入的不同数值执行不同操作:
read -p "请输入一个数字(1-3):" num
if [[ $num -eq 1 ]]; then
echo "你选择了选项1"
elif [[ $num -eq 2 ]]; then
echo "你选择了选项2"
elif [[ $num -eq 3 ]]; then
echo "你选择了选项3"
else
echo "输入无效,请重新运行脚本!"
fi
2.2 case
语句:模式匹配的利器
对于字符串匹配场景(如菜单选择),case
语句提供了更简洁的语法:
read -p "请选择操作(start/stop/restart):" action
case $action in
start)
echo "正在启动服务..."
;;
stop)
echo "正在停止服务..."
;;
restart)
echo "正在重启服务..."
;;
*)
echo "无效的操作,请重新输入!"
;;
esac
比喻:case
语句就像一个自动分拣机——根据输入的“形状”(模式),将数据导向对应的处理通道。
三、循环结构:自动化任务的核心
3.1 for
循环:已知次数的重复操作
for
循环适用于已知迭代次数的场景,如遍历文件列表或数字序列:
示例1:遍历数字序列
for i in {1..5}; do
echo "当前计数:$i"
done
示例2:处理指定目录下的所有 .log
文件
for file in /var/log/*.log; do
echo "正在压缩文件:$file"
gzip "$file"
done
3.2 while
循环:条件满足时持续执行
while
循环在条件为真时重复执行代码块,适合处理不确定次数的任务:
count=0
while [ $count -lt 3 ]; do
echo "当前计数:$count"
((count++))
done
关键点:必须确保循环有终止条件,否则可能导致无限循环。
3.3 until
循环:反向条件的控制
until
循环在条件为假时才执行,逻辑上等同于 while ! condition
:
until [ $count -eq 3 ]; do
echo "当前计数:$count"
((count++))
done
3.4 循环控制语句:break
和 continue
break
:立即退出当前循环continue
:跳过本次循环剩余代码,进入下一次迭代
for num in 1 2 3 4 5; do
if [[ $num -eq 3 ]]; then
continue # 跳过数值3
fi
echo "当前数值:$num"
if [[ $num -eq 5 ]]; then
break # 在数值5时终止循环
fi
done
四、函数与流程控制的结合
4.1 封装逻辑:函数的定义与调用
通过函数将重复的流程控制逻辑封装,可以提升代码复用性:
check_file() {
local file="$1"
if [[ -f "$file" ]]; then
echo "文件 $file 存在"
else
echo "文件 $file 不存在"
exit 1
fi
}
check_file "/etc/hosts"
4.2 错误处理:trap
命令的使用
结合 trap
可以捕获信号并执行清理操作,例如在脚本异常退出时删除临时文件:
cleanup() {
rm -f /tmp/tempfile
echo "临时文件已清理"
}
trap cleanup EXIT # 在脚本退出时执行 cleanup 函数
echo "正在运行任务..."
sleep 5
五、实战案例:构建一个备份脚本
5.1 需求分析
- 每日备份指定目录到
/backup
- 若备份目录不存在,则自动创建
- 记录备份日志到
/var/log/backup.log
5.2 脚本实现
#!/bin/bash
BACKUP_DIR="/backup"
SOURCE_DIR="/var/www"
LOG_FILE="/var/log/backup.log"
if [[ ! -d "$BACKUP_DIR" ]]; then
echo "创建备份目录:$BACKUP_DIR"
mkdir -p "$BACKUP_DIR" || exit 1 # 创建失败则退出
fi
TIMESTAMP=$(date +%Y%m%d-%H%M%S)
ZIP_FILE="$BACKUP_DIR/backup-$TIMESTAMP.zip"
echo "开始备份:$(date)" >> "$LOG_FILE"
zip -qr "$ZIP_FILE" "$SOURCE_DIR" >> "$LOG_FILE" 2>&1
if [[ $? -eq 0 ]]; then
echo "备份成功:$ZIP_FILE"
else
echo "备份失败,请检查日志文件!"
exit 1
fi
5.3 关键点解析
- 使用
mkdir -p
自动创建多级目录 zip
命令的输出重定向到日志文件- 通过
$?
检查上一条命令的退出状态
六、进阶技巧与常见问题
6.1 条件表达式中的空格陷阱
在 [ ]
中,条件两边必须有空格,否则会引发语法错误:
if [ -f$file ]; then ...
if [ -f "$file" ]; then ...
6.2 环境变量与参数传递
在脚本中,可以通过 $1
、$2
等引用命令行参数,结合条件判断实现动态行为:
ACTION=$1
case $ACTION in
start)
echo "启动服务"
;;
stop)
echo "停止服务"
;;
*)
echo "用法:$0 {start|stop}"
exit 1
;;
esac
6.3 脚本调试技巧
使用 -x
参数启用调试模式,跟踪脚本执行过程:
bash -x backup_script.sh
结论
Shell 流程控制是构建高效自动化脚本的核心能力。通过条件判断、循环结构和函数封装,开发者可以灵活应对文件操作、系统监控、批量任务等场景。本文通过基础语法、案例解析和实战脚本,系统性地展示了这一主题的实现方法。建议读者通过编写实际脚本(如日志清理工具、定时任务调度器)来巩固知识,并逐步探索 select
语句、read
命令等高级特性。掌握流程控制后,Shell 脚本将从简单的命令组合,升级为可扩展、可维护的系统管理工具。