今日目标:让脚本具备”逻辑判断”能力,并掌握数据库最核心的 CRUD(增删改查)操作。今天不只是写代码,而是要彻底理解 “如何让脚本根据条件执行不同操作”、“如何高效地操作数据库数据” 以及 “为什么 UPDATE 和 DELETE 必须加 WHERE 条件”。这是编写自动化运维工具的第一步。
学习内容 (30 mins)
在开始写代码前,先搞懂这些核心概念,否则后面的代码你会看得云里雾里。Shell 流程控制 (15 mins)
Shell 流程控制 (15 mins)
什么是流程控制?流程控制让脚本能够根据条件执行不同的操作,就像”如果…那么…否则”的逻辑。这是编写自动化脚本的核心能力。为什么需要流程控制?
- 条件执行:根据文件是否存在、服务是否运行等条件执行不同操作
- 批量处理:循环处理多个文件、多个服务器
- 错误处理:检测错误并采取相应措施
- 自动化决策:让脚本能够”思考”和”决策”
- 文件测试:
[ -f "file.txt" ]:判断文件是否存在且为普通文件[ -d "dir" ]:判断目录是否存在[ -r "file.txt" ]:判断文件是否可读[ -w "file.txt" ]:判断文件是否可写[ -x "file.txt" ]:判断文件是否可执行
- 字符串比较:
[ "$name" == "admin" ]:判断字符串是否相等[ "$name" != "admin" ]:判断字符串是否不相等[ -z "$name" ]:判断字符串是否为空[ -n "$name" ]:判断字符串是否非空- 注意:字符串比较必须用双引号包裹变量,防止空变量导致语法错误
- 数值比较:
[ $num -eq 10 ]:等于(equal)[ $num -ne 10 ]:不等于(not equal)[ $num -gt 10 ]:大于(greater than)[ $num -lt 10 ]:小于(less than)[ $num -ge 10 ]:大于等于(greater or equal)[ $num -le 10 ]:小于等于(less or equal)
- 逻辑运算符:
[ ! -f "file.txt" ]:非(NOT),文件不存在[ -f "file.txt" ] && [ -r "file.txt" ]:与(AND),文件存在且可读[ -f "file.txt" ] || [ -d "dir" ]:或(OR),文件存在或目录存在
- for 循环:
for i in {1..5}; do ... done:遍历数字序列for file in *.log; do ... done:遍历文件列表for user in alice bob charlie; do ... done:遍历字符串列表- 应用场景:批量处理文件、遍历数组、重复执行操作
- while 循环:
while [ condition ]; do ... done:条件为真时循环- 应用场景:监控服务状态、读取文件行、等待条件满足
- until 循环:
until [ condition ]; do ... done:条件为假时循环- 应用场景:等待服务启动、等待文件创建
SQL CRUD (15 mins)
SQL CRUD (15 mins)
什么是 CRUD?CRUD 是数据库操作的四个基本动作:
- Create(创建):插入新数据
- Read(读取):查询数据
- Update(更新):修改数据
- Delete(删除):删除数据
- 所有数据库操作都基于这四个动作
- 理解 CRUD 是学习复杂查询的基础
- 掌握 CRUD 能处理 80% 的日常数据库操作
- 单条插入:
- 指定字段:只插入需要的字段,其他字段使用默认值
- 不指定字段:必须提供所有字段的值(不推荐)
- 批量插入:
- 优势:一次插入多条数据,效率更高
- 应用场景:初始化数据、批量导入
-
基础查询:
-
WHERE 条件:
=:等于!=或<>:不等于>、<、>=、<=:比较运算符LIKE:模糊匹配(后续课程会讲)IN:在列表中AND、OR:逻辑运算符
-
基本语法:
-
为什么必须加 WHERE?
- 不加 WHERE:会更新所有记录(非常危险!)
- 加 WHERE:只更新符合条件的记录
- 最佳实践:更新前先用 SELECT 查询确认要更新的记录
-
更新多个字段:
- 物理删除:
- 数据从数据库中永久删除,无法恢复
- 适用于:测试数据、临时数据
- 软删除(推荐):
- 不删除数据,只标记为”已删除”
- 优势:可以恢复数据、保留历史记录
- 适用于:生产环境、重要数据
- 为什么必须加 WHERE?
- 不加 WHERE:会删除所有记录(灾难性错误!)
- 加 WHERE:只删除符合条件的记录
- 最佳实践:删除前先用 SELECT 查询确认要删除的记录
代码任务 (90 mins)
Shell 逻辑脚本
编写 常见错误:验证步骤:
02_monitor.sh,模拟简单的服务监控:任务分解:- 定义日志目录变量
- 判断目录是否存在
- 如果不存在,创建目录
- 循环生成 5 个日志文件
- 每个日志文件包含服务器状态信息
-
保存文件后,添加执行权限:
-
运行脚本:
-
检查输出:
- 应该看到 “Creating log directory…” 或 “Log directory already exists.”
- 应该看到 5 个文件创建信息
- 应该看到 “All log files created successfully.”
-
验证文件:
-
测试边界情况:
- 删除 logs 目录后再次运行脚本
- 手动创建 logs 目录后运行脚本
SQL 数据操作
编写 字段类型选择详解:
验证步骤:
02_crud.sql,对昨日的 users 表进行操作:任务分解:- 批量插入测试数据
- 查询活跃用户
- 更新用户邮箱
- 删除用户(演示物理删除,实际生产环境建议用软删除)
UPDATE 为什么必须加 WHERE?
UPDATE 为什么必须加 WHERE?
危险示例:正确做法:最佳实践:
- 更新前先用 SELECT 查询确认要更新的记录
- 在 WHERE 条件中使用唯一字段(如主键、用户名)
- 生产环境建议使用事务(后续课程会讲)
DELETE 为什么必须加 WHERE?
DELETE 为什么必须加 WHERE?
危险示例:正确做法:最佳实践:
- 删除前先用 SELECT 查询确认要删除的记录
- 生产环境建议使用软删除(UPDATE status = 0)
- 重要数据删除前先备份
软删除 vs 硬删除
软删除 vs 硬删除
硬删除(物理删除):
- 使用
DELETE FROM命令 - 数据从数据库中永久删除
- 无法恢复
- 适用于:测试数据、临时数据
- 使用
UPDATE命令修改状态字段 - 数据仍然存在,只是标记为”已删除”
- 可以恢复
- 适用于:生产环境、重要数据
-
连接 MySQL:
-
执行 SQL 脚本:
或者直接复制粘贴 SQL 语句执行
-
验证 INSERT:
-
验证 UPDATE:
-
验证 DELETE:
-
测试危险操作(仅限测试环境):
拓展任务 (30 mins)
Shell 挑战
任务:学习
while 循环,写一个脚本每秒输出当前时间,持续 5 秒后退出。提示:- 使用
while循环和计数器 - 使用
date命令获取当前时间 - 使用
sleep 1暂停 1 秒 - 思考:如何让循环在 5 秒后自动退出?
SQL 挑战
任务:学习
LIMIT(分页)和 ORDER BY(排序)的用法。提示:- 使用
ORDER BY created_at DESC按创建时间倒序排列 - 使用
LIMIT 10限制返回 10 条记录 - 思考:如何实现分页查询(第 1 页、第 2 页)?
今日产出物
day02/02_monitor.sh- Shell 监控脚本day02/02_crud.sql- SQL CRUD 操作脚本
参考代码
查看参考代码
在 GitHub 查看完整的示例代码
在线运行
使用在线编辑器测试代码
实际应用场景
Shell 流程控制在运维中的应用
- 服务监控:检查服务状态,异常时自动重启
- 文件管理:批量处理日志文件,自动清理过期文件
- 部署脚本:根据环境变量执行不同的部署流程
- 备份脚本:循环备份多个数据库或目录
- 健康检查:定期检查服务健康状态,发送告警
SQL CRUD 在生产环境的最佳实践
- INSERT:使用批量插入提高效率,避免逐条插入
- SELECT:只查询需要的字段,避免
SELECT * - UPDATE:必须加 WHERE 条件,更新前先查询确认
- DELETE:生产环境使用软删除,保留数据可恢复
- 事务管理:重要操作使用事务保证数据一致性(后续课程会讲)
上一天: 基础入门
Day 01 | Shell 基础入门与建表
下一天: 管道联表
Day 03 | Shell 管道与 SQL 联表查询