Which shell should be used for Linux/MacOS/UNIX best compatibility?

它的外壳应用于Linux和MacOS、UNIX兼容性最好?

问题 (Question)

My question may seem related to SO question "What Linux shell should I use?", but my problem is to know which shell shall be used to write an application start script, knowing that this is a cross-platform Java application (almost all Linux distributions, MacOS, Solaris, ...). So i'm adding compatibility concerns here.

Please note that i'm not asking "which is the best shell to use" in general (which may have no sense in my opinion: subjective, depends on needs), but I'd like to know, which shell has the best chance, today, to be available (and suitable for Java application start) on most operating systems.

Also, may I simply have to use the shebang #!/bin/bash to "use bash"? (or for example #!/bin/ksh for Korn shell). What if this shell is not available on this OS?

We're actually using a ".sh" file with the shebang #!/bin/sh (which is Bourne shell I guess) but some users are complaining about errors on some Linux distributions (we don't know yet which one they use, but we would also having a more global approach instead of fixing errors one by one). MacOS is currently using bash as the default shell but at this time we don't have any issue on MacOS using /bin/sh...

Note: we'd like to avoid having several start scripts (i.e. using different shells)

我的问题似乎是相关的所以问题”我应该使用什么Linux壳?“,但我的问题是知道的外壳应用于编写一个应用程序的启动脚本,知道这是一个跨平台的Java应用程序(几乎所有的Linux分布,Solaris,MacOS,……)。所以我加入相容性问题在这里。

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

另外,我可以简单的使用过程#!/bin/bash“狂欢”?(或为例#!/bin/ksh为Korn Shell)。如果在这个操作系统外壳不可用?

我们使用“。与事件SH”文件#!/bin/sh(这是我猜的Bourne Shell)但有些用户抱怨一些Linux分布误差(我们不知道哪一个他们使用,但我们也有一个更加全球化的方法代替固定误差的一个)。MacOS目前使用bash作为默认的壳,但在这个时候我们没有在MacOS使用任何问题/bin/sh

注:我们想避免的几种启动脚本(即使用不同的炮弹)

最佳答案 (Best Answer)

You won't find a shell implementation that will be installed on every of these OSes, however, all of them are either POSIX compliant or more or less close to being compliant.

You should then restrict your shell scripts to stick to the POSIX standard as far as possible.

However, there is no simple way to tell a script is to be executed in a POSIX context, and in particular to specify what shebang to set. I would suggest to use a postinstaller script that would insert the correct shebang on the target platform retrieved using this command:

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

You scripts should also include this instruction once and before calling any external command:

export PATH=$(getconf PATH):$PATH

to make sure the utilities called are the POSIX ones. Moreover, beware that some Unix implementations might require an environment variable to be set for them to behave a POSIX way (eg BIN_SH=xpg4 is required on Tru64/OSF1, XPG_SUS_ENV=ON on AIX, ...).

To develop your script, I would recommend to use a shell that has the less extensions to the standard, like dash. That would help to quickly detect errors caused by bashisms (or kshisms or whatever).

PS: beware that despite popular belief, /bin/sh is not guaranteed to be POSIX compliant even on a POSIX compliant OS.

你不会找到一个壳的实现,将被安装在每一个这些操作系统,然而,他们都是POSIX兼容的或多或少接近标准。

然后你应该限制你的shell脚本坚持POSIX标准尽可能的。

然而,有没有简单的方法来告诉脚本是一个POSIX的上下文中执行,并特别指定要设置什么事情。我会建议使用postinstaller脚本将在目标平台上正确的事情检索使用这个命令:

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

你还应该包括这个脚本指令一次调用任何外部命令之前:

export PATH=$(getconf PATH):$PATH

确保公用事业被称为POSIX的。此外,要注意的是,一些UNIX实现可能需要一个环境变量被设置为他们的行为方式(如POSIX bin_sh = XPG4是需要在Tru64 / OSF1,xpg_sus_env =在AIX上,……)。

发展你的剧本,我会推荐使用一个外壳,具有较少的扩展标准,如短跑。这将有助于快速检测所造成的bashisms错误(或kshisms等等)。

PS:要注意的是,尽管普遍的信仰,/bin/sh不能保证符合POSIX标准即使在POSIX兼容的操作系统。

答案 (Answer) 2

For maximum portability, your best bet is /bin/sh using only POSIX sh features (no extensions). Any other shell you pick might not be installed on some system (BSDs rarely have bash, while Linux rarely has ksh).

The problem you can run into is that frequently, /bin/sh is not actually Bourne sh or a strictly POSIX sh -- it's frequently just a link for /bin/bash or /bin/ksh that runs that other shell in sh-compatibility mode. That means that while any POSIX sh script should run fine, there will also be extensions supported that will cause things that are illegal per POSIX to run as well. So you might have a script that you think is fine (runs fine when you test it), but its actually depending on some bash or ksh extension that other shells don't support.

You can try running your script with multiple shells in POSIX compatibility mode (try say, bash, ksh, and dash) and make sure it runs on all of them and you're not accidentally using some extension that only one supports.

最大携带方便,最好的办法是/bin/sh使用只有POSIX SH特征(不扩展)。你选择的任何其他壳上可能未安装一些系统(BSDS很少有狂欢,而Linux很少ksh)。

你可以碰到的问题是频繁,/bin/sh不是Bourne sh或严格的POSIX SH——它经常只是一个链接/bin/bash或/斌/ KSH运行兼容性模式,其他的壳。这意味着在任何POSIX SH脚本应该运行良好,也将扩展支持将导致违法的事情每POSIX那样跑。所以你可能会有一个脚本,你认为是好的(很好,但是当你测试它)它实际上取决于一些重击或ksh扩展不支持其他的贝壳。

您可以尝试与POSIX兼容模式运行脚本的多壳(试着说,狂欢,先令,和短跑)和确保它运行在所有这些,你不小心使用了一些扩展,只有一个支持。

本文翻译自StackoverFlow,英语好的童鞋可直接参考原文:http://stackoverflow.com/questions/23437049