你的 Bash 脚本太垃圾了,用其他语言吧

2025-06-07

你的 Bash 脚本太垃圾了,用其他语言吧

(标题照片来自nixcraft的帖子,我在下面对此做出了回应)

TLDR:

  • Shell 脚本是真正的编程
  • 如果你想写 shell 脚本,好好学习它
  • 像使用其他语言一样使用编程最佳实践
  • 源代码控制
  • 它很奇怪,需要额外的关注
  • 如果以上内容不适合你,那么使用一种不那么独特的语言会更好

因此,下面是我针对一些反对意见发表的咆哮——有人建议使用 Python 而不是 bash,还有几个人抱怨它太过分,你需要两个版本的 Python 才能正确使用,或者你必须首先将它安装到机器上,诸如此类。

我热爱 Shell 脚本,至今仍在频繁使用,但我并非傻瓜。它存在诸多问题,因此盲目地为它辩护,认为它适用于所有场景,实属愚蠢之举。

尤其因为在公司环境中,你一起工作的大多数人根本不知道如何使用 Shell 脚本。他们想到把脚本放到源代码管理里就能获得加分,就像在考试上写上你的名字就能获得分数一样。

Shell 脚本才是真正的编程。它应该进行源代码控制,代码审查,并按照干净、可维护的标准编写。因为这些代码是用于生产的。

因此我是这样反驳的:


如果是个人机器,请安装 Python 或其他选择的语言。

如果是企业机器,则需要制定策略来确保使用 Python 或其他选择的语言。

Shell 确实很棒,我自己也是个命令行迷,现在很多工作还是会用到 Shell 脚本,但是一个 Shell 脚本,如果只是用来绕接一两个长管道,很快就会让人抓狂,除非你真的花时间和精力好好学习这门语言。(文章里的配图就是一个烂到极致的代码示例,他们的问题还不在于文件名空格,而在于他们对变量的处理太垃圾了,而且根本不想把代码写得干净利落。)

我是一位资深的Bash 脚本编写者,一直以来之所以如此,完全是因为这里列出的这些原因,我曾经认为这些原因都是合理的。所有这些原因都可以绕过——而且解决“X 语言不在我们的机器集群上”的开销,往往比你多年来编写的数十个难以维护、从未维护过的脆弱 Shell 脚本,或者你的同事无法理解、无论如何都不愿碰的 Shell 脚本,回报更高。这些难以理解的 Shell 脚本运行着部署、构建、集群管理等任务的主干——而这些任务正是许多公司的主干。

我见过经验丰富的开发人员写的 Bash 脚本,它们也完全是垃圾。你的代码可能比平均水平更干净,但这标准太低了。

Shell 脚本本身就很优秀、很强大,这一点毋庸置疑。我一直提倡大家好好尝试并学习它,但可悲的是,现实是没有人真正去做。如果是任何一门“正统”的语言,人们都会很乐意学习它的精髓,无论是出于同行的期望还是遗传下来的偏见;但 Shell,即使学得很好,也会有人因为懒得学习而把你干净的代码搞砸。

我一直在敦促开发人员和管理员真正学会正确使用 bash/shell,利用函数,封装逻辑步骤,编写简洁的代码。“这只是一个 shell 脚本”、“太过分了”、“这样就好了”、“我不想花时间学习这个,反正它也不是一门真正的语言”。

另一个事实是,在系统管理员领域,大多数人甚至不能编写干净的 Python/Ruby/Perl/PHP/JavaScript/chosen-lang,并且考虑到 shell 让你逃脱的陷阱数量和事情,直到你遇到灾难性的错误(由于程序员的粗心,误解的 shell 行为是有记录的)(Steam 错误?),他们最好在比 shell 脚本更安全的环境中。

Shell 脚本中经常出现的问题并不是程序员的错:

  • 很乐意让你默认摆脱未定义的变量(除非你明确set -ue
  • 比较与赋值是唯一需要注意空间的地方(a=b并且a = b是完全不同的语句,wtf)
  • 函数不能返回数组,只能返回文本流(这是函数的强大之处,也是它的致命弱点)(这个问题加剧了其他许多问题,因为它阻止了编写变通函数)
  • 数组不能作为与其他参数不同的项传递给函数(你可以使用引用作为解决方法,但是有多少 bash 脚本编写者知道这些?)(使用全局变量更容易,对吧?真恶心)
  • 变量默认是全局的。除非你把迭代计数器设为本地变量,否则你肯定会看到一些奇怪的错误。
  • 字符串拆分是围绕字符串的固有部分进行的,而不是作为对其操作的函数(我们都知道 IFS 吗?每个人都知道如何使用它吗?我不这么认为)
  • 你运行的真的是你以为的那个 shell 吗?你是否曾经部署过 bash 脚本,却发现机器上唯一的解释器是sh?或者环境sh默认强制你使用 ?又或者你实际上并没有运行bashash又或者系统默认是dash?总之,你现在必须用纯文本编写所有内容,并失去所有曾经带来、使任务更容易完成的sh改进。bash
  • 常用命令的环境不一致的情况屡见不鲜。你的脚本使用了“邮件”功能吗?GNU 还是 BSD,该使用哪些选项?你使用的是netcat哪个版本?哪个选项?你使用的tar是 、greprsync?你使用的是 GNU、BSD 还是 Busybox 实现?(在混合部署 Ubuntu、CentOS 和 Alpine 时,这些差异层出不穷,而这还只是冰山一角)
  • (我嘲笑任何“确保公司系统上 Python 版本正确”的反对意见)
  • 尝试任何稍微有点事件驱动的事情都会产生一堆令人讨厌的变通方法(我试过,但收效甚微)。诚然,shell 的设计初衷显然不适合这种领域,但这就是我曾经尝试用 shell 做所有事情的程度。虽然有可能,但用其他语言会更好,这实在太难了。

最根本的是,将 Shell 视为“不是一种合适的语言”的观点阻碍了人们正确、深入地学习它,并理解其自身特性的动力。至少对于其他语言中的一种,开发人员都继承了一种思维模式,认为他们对该语言的技能需要持续改进,并会为此而努力。

我仍然在写大量的 Bash 脚本。我很喜欢它。但建议其他人使用其他语言更明智。我个人也选择了 Python。但最终,除非你打算拼尽全力去学习它,否则我不会推荐它。好好学习它。

文章来源:https://dev.to/taikedz/your-bash-scripts-are-rubbish-use-another-language-5dh7
PREV
回调和承诺的简单解释
NEXT
为在家工作的程序员和努力毕业的学生提供生产力和动力提示。