哪个shell应该用于Linux / MacOS / UNIX最佳兼容性?

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

请注意, 我并不是问 一般最好使用哪一个壳” (在我看来这可能没有意义:主观的,取决于需求),但是我想知道哪个壳有最好的机会今天,在大多数操作系统上都可用(并适用于Java应用程序的启动)。

另外,我可以简单地使用shebang #!/bin/bash“使用bash”吗? (或者例如Korn shell的#!/bin/ksh )。 如果这个shell在这个操作系统上不可用呢?

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

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

你不会在每个操作系统上找到一个shell实现,但是,它们都是POSIX兼容的,或者更接近于兼容。

你应该尽可能的限制你的shell脚本来遵守POSIX标准 。

但是,没有简单的方法来告诉脚本要在POSIX上下文中执行,特别是指定要设置的脚本。 我建议使用postinstaller脚本,它将在使用此命令检索的目标平台上插入正确的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)。

为了开发你的脚本,我建议使用一个具有较少的标准扩展的外壳,比如破折号。 这将有助于快速检测由bashisms(或kshisms或其他)引起的错误。

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

为了获得最大的可移植性,最好的办法是使用POSIX sh特性(不能扩展) /bin/sh 。 你选择的任何其他shell可能没有安装在某些系统(BSD很少有bash,而Linux很少有ksh)。

你可以碰到的问题是,/ bin / sh经常不是实际的Bourne sh或者是严格的POSIX sh – 它经常只是一个链接/ bin / bash或者/ bin / ksh,以sh-compatible模式。 这意味着,虽然任何POSIX SH脚本应该运行良好,但也会有支持的扩展,这将导致每个POSIX不合法的事情运行。 所以你可能有一个你认为没问题的脚本(当你测试的时候运行正常),但是它实际上取决于其他shell不支持的bash或者ksh扩展名。

你可以尝试在POSIX兼容模式下运行你的脚本(试试说,bash,ksh和破折号),确保它们运行在所有的脚本上,并且不会意外地使用一些只支持的脚本。