编程与软件工程arslan.io
如何编写幂等的 Bash 脚本
How to write idempotent Bash scripts
2019 — 2021,它一次次回到首页
黑点是上首页(≥ 50 分)的那次投稿,空心点是没冲上去的投稿,点越大分数越高。
导读
这篇 2019 年的文章介绍如何编写幂等的 Bash 脚本,即脚本可以安全地重复执行而不会产生副作用。作者通过 mkdir、rm、ln 等常见命令的示例,展示如何用 -p、-f 等标志让命令在目标已存在或不存在时也能正常工作。
为什么经久不衰:自动化运维中脚本被反复执行是常态,幂等性是避免误操作的关键思路,而评论区的争论(幂等 vs set -e vs 声明式工具)本身就是一份很好的学习材料。
HN 评论精选
与其手写幂等脚本,不如用 Chef 等声明式配置工具,甚至直接每次从零构建环境。
了解哪些命令行工具是幂等的固然好,但一旦要反复运行自动化脚本,更好的选择是用 Chef 这类工具,以声明式方式定义最终状态,让工具自己收敛到该状态。比如“创建目录”的例子,你只需声明“最终这个目录存在且具有这些权限”,Chef 会判断目录是否已存在。当然这种方式也有缺点:你不可能声明所有事情,比如之后删掉该声明,Chef 并不会去删除那个目录。所以理想情况是每次都从零构建基础设施(如 Docker),而不是去收敛一台已有机器。
mnutt查看英文原文
It’s good to know which command line tools are idempotent, but I think once you start running automated scripts repeatedly you’re better off with something like Chef where you declaratively define the end state and let chef figure out how to converge upon that state. Taking the “create a directory” example, you would say “I want to end up in a state where this directory is created and has these permissions” and chef will determine if the directory already exists. There are of some downsides to that approach which stem from the fact that you can’t possibly declare every possible thing. For instance, if you were to run the above declaration and then later remove the declaration, chef wouldn’t know to delete the directory; at that point chef wouldn’t know anything about the directory at all. So ideally you can build infrastructure from scratch each time (Docker, etc) rather than having to converge an existing machine.
反对文章思路:Bash 脚本无法真正幂等,应该用 set -e 做严格的错误处理。
这总体上是很糟糕的建议。更好的做法是用 'set -e',确保脚本在出错时立即退出。Bash 脚本不可能真正幂等,因为它运行在一个永远无法保证幂等的外部环境中。更稳妥的做法是格外小心地处理错误。
united893查看英文原文
This is generally terrible advice. A better option is to 'set -e' and ensure that the bash script exits when there's a failure. Bash scripts can't be idempotent because they operate in an external environment that can't ever be. The better option is to just be extra safe. See: > http://redsymbol.net/articles/unofficial-bash-strict-mode/
警告 -f 等强制标志有破坏性,盲目使用可能在首次运行时就造成意外。
这些标志确实值得了解,但我不同意文章的前提。很多标志之所以不是默认行为,是因为它们可能极具破坏性。如果脚本本身有错误、你预期还会出错,你真的想让所有命令强行推进、删除和覆盖东西吗?让人不加思考地总是使用这些标志无异于玩火。这也许能让脚本在重复运行时幂等,但第一次运行的结果可能完全出乎意料。
empath75查看英文原文
This is surely a good collection of flags to know, but I sort of object to the premise of the article. There is a good reason that many of these flags are not default behavior, and it’s that they can be quite destructive. If you’re writing a script, as the beginning scenario says, that has errors in it, and you expect to have more, do you really want to tell all the commands to power through and delete and overwrite stuff if it encounters an unexpected state? Telling people to just always use these flags and not only when they’re quite sure what their script is doing, is probably playing with fire. This may make the script idempotent in repeated runs, but the first run might not be what you expect at all.
亲历者经验:Bash 幂等化成本高,规模变大后切换 Ansible 更划算。
我曾经尝试过这样做,额外的测试成本和增加的复杂度让这一切并不值得。改用 Ansible 后效率高得多。有趣的是,从 Bash 起步是个不错的 MVP 方式——上手快,但随着项目变慢就该换更好的工具了。很多项目的 Bash 脚本可能永远多到不值得切换的程度,所以写可以安全重复运行的脚本没问题,但如果维护成本增长,要知道还有更好的工具。
josho查看英文原文
I tried doing this once. It just wasn't worth the additional testing effort and increased complexity. Switching to Ansible was far more productive. Interestingly though starting in Bash was a good MVP approach. Fast to get started. But as things started to slow down the project switched to a better tool. I expect for many projects the number of bash scripts may never grow large enough to merit a switch. So, sure write scripts that are safe to run multiple times, but if that effort grows know that there are better tools.
历次讨论
同类还值得读
开源应用架构
The Architecture of Open Source Applications
《开源软件架构》(AOSA)是一本在线免费书,邀请知名开源项目的作者亲自剖析其内部设计,涵盖 SQLAlchemy、LLVM、Audacity、Apache、Bash 等系统。
编程与软件工程上首页 9 次 · 2011–2024aosabook.org编辑精选编程语言简史:简短、不完整且多半错误
A Brief, Incomplete, and Mostly Wrong History of Programming Languages
一篇以戏谑、故意不准确的方式回顾编程语言史的博客文章,用夸张轶事和讽刺定义串起 Lisp、C、C++、Java、JavaScript、PHP 等语言。
编程与软件工程上首页 8 次 · 2009–2021james-iry.blogspot.comSQLite 是如何测试的
How SQLite is tested
SQLite 官方文档页,系统介绍 SQLite 的测试体系:多种测试方法(TCL 测试、模糊测试、回归测试、静态分析等)和海量测试用例,展示了这个小型开源项目如何靠极致测试获得…
编程与软件工程上首页 8 次 · 2009–2025sqlite.org编辑精选高级编程语言(2009)
Advanced programming languages (2009)
Matt Might 的经典文章,按用途推荐“高级编程语言”:如果追求就业就选主流语言,如果追求表达力、学术研究或创业,则推荐 Haskell、OCaml、Scala 等函数式语…
编程与软件工程上首页 8 次 · 2009–2022matt.might.net我的 Forth 与栈机器经历
Yosefk - My history with Forth & stack machines
作者以亲身经历回顾了使用 Forth 语言和栈式机器的历程:既赞叹其简洁优雅、代码量小、可自举的优点,也坦率指出栈操作在实际编程中的痛苦,以及 Forth 社区文化中的问题。
编程与软件工程上首页 8 次 · 2010–2024yosefk.com编辑精选