差别不在语言而在工程属性
临时脚本写出来是为了解决当下的一次问题:路径写死、失败就重跑、没有文档、作者本人就是唯一说明书。工程化剧本要求同样的事情在别人手里、半年以后、环境变了之后仍能跑对:参数从外部传入、重复执行结果一致、失败有明确处理、执行过程留痕、变更走评审与版本控制。两者可以是同一种语言写的,区别在于是否补齐了工程属性。
基本信息
| 临时脚本特征 | 写死路径、无参数、无错误处理、无版本管理 |
|---|---|
| 工程化特征 | 可参数化、幂等、可回滚、可审计、受版本控制 |
| 升级代价 | 主要投入在边界处理与文档,而非重写逻辑 |
| 责任人 | 必须有明确维护者与变更流程 |
需要补齐的五项属性
- 幂等性:重复执行不产生额外变化,支持安全重跑。
- 参数化:环境差异通过变量传入,脚本内容不随环境复制。
- 错误处理:区分可重试与不可重试失败,失败时返回明确状态。
- 执行留痕:输出关键动作与变更结果,便于事后定位。
- 版本与评审:资产纳入版本控制,改动经过审阅而非直接覆盖。
同一件事的两种写法
同一件事的两种写法
# 临时脚本:路径写死,无判断,重跑会重复追加
# echo 'listen=9000' >> /etc/app/app.conf
# 工程化版本:参数化 + 幂等 + 校验 + 留痕
set -euo pipefail
target=${TARGET_FILE:?需要传入 TARGET_FILE}
value=${LISTEN_PORT:?需要传入 LISTEN_PORT}
if ! grep -qxF "listen=${value}" "${target}"; then
echo "listen=${value}" >> "${target}" # 只在缺失时追加
fi
grep -qxF "listen=${value}" "${target}" && echo 'OK: 配置已生效' # 后置校验工程化检查项
| 属性 | 脚本化表现 | 工程化要求 |
|---|---|---|
| 幂等 | 重跑会重复追加 | 重跑结果一致 |
| 参数 | 路径写死在文件里 | 由变量或参数传入 |
| 错误处理 | 出错继续往下跑 | 区分失败类型并中断 |
| 留痕 | 无日志或只打印进度 | 记录变更前后差异 |
| 版本 | 存在个人目录里 | 纳入版本控制并评审 |
判断一个脚本是否值得工程化升级,看它的执行频率与影响面:每周执行、影响生产流量的脚本优先升级;一次性迁移脚本明确标注有效期,到期归档即可,不必强行改造。