我为何用30行Bash脚本替换了一个Node.js服务——以及何时不应这样做

发布日期:2026-06-14 10:02:22   浏览量 :4
发布日期:2026-06-14 10:02:22  
4

几个月前,我有一个需要自动化的小任务:每天从我网站上获取一个统一资源定位符(URL)列表,并通知谷歌和必应这些页面已更改,以便新页面能在几小时内而不是几天内被索引。显而易见的方案是构建一个微型的 Node.js 服务——引入一个谷歌应用程序接口(API)客户端、一个 IndexNow 辅助工具和一个调度库,将其部署在服务器上,即可完成。

我首先构建了 Node.js 版本。它确实能运行。但它也引入了四十多个传递依赖项,需要在服务器上拥有自己的运行时环境,并且在三周后因为一个次要版本更新改变了身份验证辅助函数的签名而崩溃。对于一个每天只运行一次、仅用于签署令牌并发布一些 JavaScript 对象表示法(JSON)数据的脚本来说,这需要维护的表面面积太大了。

于是我删除了它,并用大约三十行 Bash 代码重写了整个程序:curlopenssljq。从那以后,它每晚都在运行,且无需任何依赖项更新。以下是关于这种权衡何时值得、以及何时绝对不值得的诚实分析。

Bash 在哪些方面悄然表现出色

两个“困难”的部分其实并不难。签署谷歌服务账户的 JSON Web 令牌(JWT)——这是每个软件开发工具包(SDK)都隐藏在函数调用背后的操作——仅仅是对头部和声明集进行 base64url 编码,使用 openssl dgst -sha256 -sign 对点分字符串进行签名,然后对结果进行 base64url 编码。这只需要四行代码。将其交换为访问令牌只需一次 curl 请求。提交到 IndexNow 也只需再发一次请求。

一旦编写完成,其吸引力不在于巧妙,而在于几乎没有什么东西会出错。没有需要审计的 node_modules 目录,不需要在主机上修补运行时环境,也没有锁文件漂移问题。整个程序在一屏之内即可从头到尾清晰阅读。当出现问题时,失败表现为日志中可见的超文本传输协议(HTTP)状态码,而不是深埋在我未编写的库中三层之下的异常。

对于狭窄、稳定且受输入/输出(I/O)限制的任务——按计划调用应用程序接口(API)、解析少量 JavaScript 对象表示法(JSON)数据、记录结果——Bash 加上 curl/jq 是一个真正合适的选择,而“无依赖项”是一个特性,而非一种炫耀。

这种方法不再适用的情况

以下是那些主张“只用 Bash”的人群所忽略的部分。一旦我的需求增长,所有优势都发生了逆转。

  • 任何涉及状态或分支逻辑的情况。 我的配额跟踪器——“每天处理 200 个统一资源定位符(URL)后停止”——已经是脚本中最丑陋的部分。当我需要带有退避策略的重试机制时,我感觉到这门语言在与我作对。控制流和数据结构正是 Bash 变得混乱不堪的地方。
  • 任何需要测试的情况。 对于一堆 curl 调用,没有舒适的单元测试方案。我的“测试套件”就是运行它并阅读日志。对于一个每日索引器来说,这是可以接受的;但对于任何业务依赖的关键系统,则不可接受。
  • 任何由其他人维护的情况。 巧妙的 Bash 单行命令是一种“只写”介质。下一位工程师——或者六个月后的我——将会阅读这三十行包含 tr 和进程替换的代码,并默默地用 Python 重写它。
  • 任何涉及真正解析的情况。 当你第一次试图使用正则表达式从超文本标记语言(HTML)中提取字段或处理嵌套的 JavaScript 对象表示法(JSON)边缘情况时,请停止。jq 有其局限性,而 Bash 的字符串处理能力局限更多。

真正的准则

决策的关键不在于“Bash 还是 Node”。而是这将发生多少变化,以及谁必须与之共存。 一个按定时器执行单一稳定任务、由你拥有、且失败时发出响亮且可见警报的脚本——在这种情况下,摆脱运行时环境和依赖树是一个真实且持久的胜利。一旦它需要状态管理、测试、团队成员协作或非平凡的解析,你所移除的依赖项原本是在为你购买某种保障,你应该把它们买回来。

我保留

免责声明:本文内容来自互联网,该文观点不代表本站观点。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,请到页面底部单击反馈,一经查实,本站将立刻删除。

关于我们
热门推荐
合作伙伴
免责声明:本站部分资讯来源于网络,如有侵权请及时联系客服,我们将尽快处理
Copyright © 2025-2027 ToB产业网址导航 公安备案 浙公网安备33010602013138号 浙ICP备16025413号-9
支持 反馈 订阅 数据