Shell 脚本的幂等性:让重复执行不再出问题
写运维脚本时最容易踩的坑,是脚本只能跑一次:第一次成功,第二次就报错,或者重复执行产生重复结果。幂等性就是让脚本无论执行一次还是多次,最终结果都一样。下面是几个在实践中真正管用的做法。
一、先判断,再执行
不要假设目标状态不存在。创建目录前先检查:test -d /data/app || mkdir -p /data/app。写配置文件前先判断内容是否已存在,存在就跳过。把“如果已经是想要的状态就什么都不做”作为每一步的默认分支,脚本自然就有了幂等性。
二、用原子操作代替“删了再建”
先写临时文件、写完再 mv 覆盖目标文件,是比直接覆盖更安全的做法:mv 是原子操作,中途失败不会留下一个写了一半的文件。更新配置、替换证书、部署静态文件都适用这个模式。配合 mktemp 生成临时文件,用完记得清理。
三、给重复操作加唯一标识
向数据库或 API 写数据时,带上业务唯一键:INSERT … ON CONFLICT DO NOTHING,或者用请求幂等键(Idempotency-Key)。这样即使脚本因为网络超时被重试,也不会产生重复记录。重试逻辑本身也应该是幂等的:重试前先查询当前状态,而不是无脑重发写操作。
四、失败要停在可恢复的状态
脚本开头加 set -euo pipefail,让任何一步失败就立即退出,而不是带着错误状态继续往下跑。关键步骤执行前打印日志、执行后校验结果:比如重启服务后检查进程是否真的起来了,curl 健康检查接口返回 200 才算完成。失败时留下的应该是“上一步已完成、下一步还没做”的干净状态,而不是一半新一半旧。
五、把副作用收敛到最小
能用声明式工具就别手写循环:包管理器、配置管理工具本身就是幂等的。手写脚本时,把所有写操作集中在少数几个函数里,读操作和写操作分开,这样 review 时一眼就能看出重复执行会发生什么。
结尾:幂等性不是锦上添花,而是运维脚本的基本要求。写脚本时多问一句“这行命令跑第二遍会怎样”,能省下深夜排障的大把时间。
- 点赞
- 收藏
- 关注作者
评论(0)