首页/系统与基础设施/自动化运维速查/临时脚本与工程化剧本的差异
自动化基础与选型50 条

临时脚本与工程化剧本的差异

临时脚本以「这次把事办成」为目标,工程化剧本以「长期可重复、可协作、可回滚」为目标;差别体现在幂等性、参数化、错误处理、日志与版本控制这几项上。把脚本升级为工程化资产的核心动作不是换工具,而是补齐这五项工程属性并明确责任人。

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌​​​‌‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌‌​​​​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌‌‌​​‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​

差别不在语言而在工程属性

临时脚本写出来是为了解决当下的一次问题:路径写死、失败就重跑、没有文档、作者本人就是唯一说明书。工程化剧本要求同样的事情在别人手里、半年以后、环境变了之后仍能跑对:参数从外部传入、重复执行结果一致、失败有明确处理、执行过程留痕、变更走评审与版本控制。两者可以是同一种语言写的,区别在于是否补齐了工程属性。

基本信息

临时脚本特征写死路径、无参数、无错误处理、无版本管理
工程化特征可参数化、幂等、可回滚、可审计、受版本控制
升级代价主要投入在边界处理与文档,而非重写逻辑
责任人必须有明确维护者与变更流程

需要补齐的五项属性

  • 幂等性:重复执行不产生额外变化,支持安全重跑。
  • 参数化:环境差异通过变量传入,脚本内容不随环境复制。
  • 错误处理:区分可重试与不可重试失败,失败时返回明确状态。
  • 执行留痕:输出关键动作与变更结果,便于事后定位。
  • 版本与评审:资产纳入版本控制,改动经过审阅而非直接覆盖。

同一件事的两种写法

同一件事的两种写法
# 临时脚本:路径写死,无判断,重跑会重复追加
# 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: 配置已生效'  # 后置校验

工程化检查项

属性脚本化表现工程化要求
幂等重跑会重复追加重跑结果一致
参数路径写死在文件里由变量或参数传入
错误处理出错继续往下跑区分失败类型并中断
留痕无日志或只打印进度记录变更前后差异
版本存在个人目录里纳入版本控制并评审
判断一个脚本是否值得工程化升级,看它的执行频率与影响面:每周执行、影响生产流量的脚本优先升级;一次性迁移脚本明确标注有效期,到期归档即可,不必强行改造。

易错点

  • 把脚本直接放进共享仓库就当成工程化:幂等性与错误处理都没补,别人一跑就出错,反而扩大影响面
  • 参数化只做一半:路径参数化了但凭据仍写死在脚本里,敏感信息随资产扩散
  • 缺少失败语义:脚本中途失败也返回成功,编排工具误判为完成,后续步骤在错误状态上继续执行
  • 没有明确维护者:资产在仓库里但无人负责,出问题时所有人都认为该由别人改

数据来源与参考

  • Red Hat《Ansible 官方文档:最佳实践与角色结构》
  • Google SRE 工作手册(可靠性与变更工程章节)
  • Git 官方文档(版本控制基础工作流)

整理校对:其其网ICT文档中心 · 本页地址:docs.qiqicto.com/automation/script-vs-engineered-playbook.html

​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌​​‌​‌‌‌‌​‌‌​​​​‌​‌‌‌​‌​‌​‌‌‌​‌​​​‌‌​‌‌‌‌​‌‌​‌‌​‌​‌‌​​​​‌​‌‌‌​‌​​​‌‌​‌​​‌​‌‌​‌‌‌‌​‌‌​‌‌‌​​​‌​‌‌‌‌​‌‌‌​​‌‌​‌‌​​​‌‌​‌‌‌​​‌​​‌‌​‌​​‌​‌‌‌​​​​​‌‌‌​‌​​​​‌​‌‌​‌​‌‌‌​‌‌​​‌‌‌​​‌‌​​‌​‌‌​‌​‌‌​​‌​‌​‌‌​‌‌‌​​‌‌​​‌‌‌​‌‌​‌​​‌​‌‌​‌‌‌​​‌‌​​‌​‌​‌‌​​‌​‌​‌‌‌​​‌​​‌‌​​‌​‌​‌‌​​‌​​​​‌​‌‌​‌​‌‌‌​​​​​‌‌​‌‌​​​‌‌​​​​‌​‌‌‌‌​​‌​‌‌​​​‌​​‌‌​‌‌‌‌​‌‌​‌‌‌‌​‌‌​‌​‌‌​​‌​‌‌‌​​‌‌​‌​​​​‌‌‌​‌​​​‌‌​‌‌​‌​‌‌​‌‌​​