拜占庭教义存在什么问题?

拜占庭教义存在什么问题?

我所说的“Bashism”是指只有 bash shell 能理解而其他 shell 不能理解的 shell 语法。

如果你编写的脚本仅在/bin/bash存在的环境中执行,那么我认为避免 Bashism 是无用的并且浪费时间,但也许我遗漏了一些东西。

如果允许使用仅在 Bash 中可用的功能,那么有更简单的解决方案,那么以更复杂的方式编写脚本有什么好处呢?

有一个后续问题:有没有关于 bash 和 dash 速度的具体数据?

我在这里发表了我的结论:https://github.com/guettli/programming-guidelines/#portable-shell-scripts

答案1

首先,可移植性。如果您确信使用脚本的任何地方都会有 bash(最好是相同或更新的版本),那就没有问题。如果您是一名开发人员或系统管理员,希望软件在 Ubuntu 以外的类 Unix 操作系统上使用,并且他们可能有也可能没有bash,那么 bashisms 将无法被理解/bin/sh

第二,POSIX 合规性。如果您编写并提交脚本以将其作为操作系统或项目的一部分,则通常需要符合/bin/sh语法,这基本上就是 POSIX 标准。 /bin/sh出于性能原因,通常是首选,因此如果您需要 shell 脚本的速度,那么 bashisms 和 bash 可能是您应该避免的东西。

简而言之,bashism 并不坏。这实际上取决于您编写脚本的上下文。如果确定 bash 可用,并且不太过时,那么无论如何都要使用这些功能 - 它们存在是有原因的。

答案2

没什么,如果你知道你正在使用特定于 Bash 的功能,并记得使用 hashbang#!/bin/bash而不是假设/bin/sh是 Bash。

在 Ubuntu(和 Debian)中,脚本中的“bashisms”#!/bin/sh主要是一个问题,当默认设置/bin/sh更改为 Dash 而不是之前的 Bash 时(请参阅Ubuntu wiki 中的 DashAsBinSh)。所有运行的脚本/bin/sh都必须检查是否有 bashism,并修复以使用 Dash 支持的标准功能。更改与 Bash 的可用性无关(它仍然是一个Essential包,因此始终安装),而是与速度有关:在 systemd 之前,启动过程会产生大量 shell 脚本,将默认 shell 更改为更快的 shell 实际上会产生影响。

在其他系统上,/bin/sh可能仍然是 Bash,因此可能会在标有 的脚本中意外使用 Bash 特有的功能#!/bin/sh。它们无法在sh没有 Bash 的系统中直接工作。还有一些系统根本没有 Bash。嵌入式系统通常只有 Busybox shell。非 Linux Unixen 可能没有 Bash,但它们通常有某个版本的 ksh,Bash 的许多功能都来自 ksh。但是,它们并不是 1:1 兼容的。

Bash 中的一些非标准功能非常有用(例如数组、子字符串切片 ( ${var:n:m})、文本替换 ( ${var/foo/bar})),因此如果它们使您的脚本更容易编写,请务必使用 Bash。

话虽如此,有些 bashism 有直接的标准等价物,这意味着几乎没有理由使用非标准变体。以下是一些浮现在脑海中的东西:

  • ==中的运算符是[ .. ]非标准的,但相当于标准=运算符
  • function f { ... }f() { ... }在 Bash 中是等效的,但前者是非标准的。(它来自 ksh,两者有区别。)
  • $((--n))是非标准的,但可以替换为$((n=n-1))
  • 在简单情况下[[ ... ]]可以用标准替换[ .. ]

相关内容