【问题标题】:Which shell should be used for Linux/MacOS/UNIX best compatibility?Linux/MacOS/UNIX 最佳兼容性应该使用哪个 shell?
【发布时间】:2014-06-19 15:55:58
【问题描述】:

我的问题可能看起来与 SO 问题“What Linux shell should I use?”有关,但我的问题是知道应该使用哪个 shell 来编写应用程序启动脚本,知道这是一个跨平台Java 应用程序(几乎所有 Linux 发行版、MacOS、Solaris,...)。所以我在这里添加兼容性问题

请注意,我不是在问 “哪个是最好的外壳”(我认为这可能没有意义:主观,取决于需要),但我想知道,今天哪个 shell 最有可能在大多数操作系统上可用(并且适合 Java 应用程序启动)。

另外,我是否只需使用 shebang #!/bin/bash“使用 bash”? (或者例如 #!/bin/ksh 用于 Korn shell)。如果这个 shell 在这个操作系统上不可用怎么办?

我们实际上使用的是带有 shebang #!/bin/sh 的“.sh”文件(我猜是 Bourne shell),但是一些用户抱怨某些 Linux 发行版上的错误(我们还不知道他们使用的是哪一个) ,但我们希望采用更全局的方法,而不是一个一个地修复错误)。 MacOS 目前使用 bash 作为默认 shell,但目前我们在 MacOS 上使用 /bin/sh 没有任何问题...

注意:我们希望避免使用多个启动脚本(即使用不同的 shell)

【问题讨论】:

  • 不要使用#!/bin/sh。 POSIX 允许兼容的实现在那里提供一个不可移植的 shell 解释器。
  • @jlliagre 谢谢。所以如果/bin/sh不能保证符合POSIX,应该使用哪个shebang?
  • 我在回复中解释了如何为特定平台获取它。

标签: linux macos shell unix compatibility


【解决方案1】:

您不会找到将安装在所有这些操作系统上的 shell 实现,但是,它们都符合 POSIX 或或多或少接近符合标准。

然后你应该限制你的 shell 脚本尽可能地坚持POSIX standard

但是,没有简单的方法可以告诉脚本要在 POSIX 上下文中执行,尤其是指定要设置的 shebang。我建议使用安装后脚本,在使用此命令检索的目标平台上插入正确的 shebang:

#!/bin/sh
printf "#!%s\n" `PATH=\`getconf PATH\` command -v sh`

您的脚本还应该在调用任何外部命令之前包含该指令一次:

export PATH=$(getconf PATH):$PATH

确保调用的实用程序是 POSIX 的。此外,请注意某些 Unix 实现可能需要设置环境变量以使其以 POSIX 方式运行(例如,在 Tru64/OSF1 上需要 BIN_SH=xpg4,在 AIX 上需要 XPG_SUS_ENV=ON,...)。

要开发您的脚本,我建议使用对标准的扩展较少的 shell,例如 dash。这将有助于快速检测由 bashism(或 kshism 或其他)引起的错误。

PS:请注意,尽管普遍认为,/bin/sh 并不保证符合 POSIX,即使在符合 POSIX 的操作系统上也是如此。

【讨论】:

  • 谢谢。因此,如果不能保证 /bin/sh 符合 POSIX,我应该使用哪个 shebang?
  • 正如我所写的,您无法提前知道 shebang 应该是什么。最好的方法是使用在目标平台上安装脚本后设置/更新它的脚本。
  • 好的,谢谢! (确实你在回答中解释了,我的错!)
  • 很遗憾,您接受的答案错过了这一点,特别是提出了在 Solaris 10 及更早版本上会失败的问题。
  • 事实上,我正在等待对您的解决方案的当前测试结束 (getconf PATH)。如果您的回答比其他回答更能帮助我们,我当然不会接受第一个回答,而是接受您的回答。我最初接受另一个问题,因为在安装后动态修改 shebang 对我来说似乎有点复杂或矫枉过正,但我​​可能错了,我们正在几个操作系统上对此进行测试。谢谢!
【解决方案2】:

为了最大可移植性,您最好的选择是/bin/sh使用 POSIX sh 功能(无扩展)。您选择的任何其他 shell 可能不会安装在某些系统上(BSD 很少有 bash,而 Linux 很少有 ksh)。

您经常会遇到的问题是,/bin/sh 实际上并不是 Bourne sh 或严格的 POSIX sh——它通常只是运行其他 shell 的 /bin/bash 或 /bin/ksh 的链接sh 兼容模式。这意味着虽然任何 POSIX sh 脚本都应该可以正常运行,但也会支持一些扩展,这将导致每个 POSIX 非法的东西也可以运行。所以你可能有一个你认为很好的脚本(当你测试它时运行良好),但它实际上取决于其他 shell 不支持的一些 bash 或 ksh 扩展。

您可以尝试在 POSIX 兼容模式(例如 bash、ksh 和 dash)下使用多个 shell 运行您的脚本,并确保它在所有这些 shell 上运行,并且您不会意外使用只有一个支持的扩展。

【讨论】:

  • 很好的答案。如果可以,我会接受这两个答案(@Chris Dodd 和 @jlliagre)。对于未来的读者:我接受了 jlliagre 的回答,因为我认为使用 dash 测试脚本就足够了(无需在 POSIX 模式下使用其他 shell IMO 进行测试),然后在某些派生的 UNIX 上可能需要动态更新 shebang。跨度>
猜你喜欢
  • 1970-01-01
  • 2017-04-16
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 2021-04-05
  • 2012-11-06
  • 2011-10-05
  • 1970-01-01
相关资源
最近更新 更多