Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/macos/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux/MacOS/UNIX最佳兼容性应使用哪个shell?_Linux_Macos_Shell_Unix_Compatibility - Fatal编程技术网

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

Linux/MacOS/UNIX最佳兼容性应使用哪个shell?,linux,macos,shell,unix,compatibility,Linux,Macos,Shell,Unix,Compatibility,我的问题似乎与问题“”有关,但我的问题是知道应该使用哪个shell来编写应用程序启动脚本,因为我知道这是一个跨平台的Java应用程序(几乎所有Linux发行版、MacOS、Solaris等等)。因此,我在这里添加了兼容性问题 请注意,我并不是问一般情况下“哪种shell最好使用”(在我看来可能没有意义:主观的,取决于需要),但我想知道,今天,哪种shell最有可能在大多数操作系统上可用(并且适合Java应用程序启动) 另外,我可以简单地使用shebang#吗/bin/bash要“使用bash”吗

我的问题似乎与问题“”有关,但我的问题是知道应该使用哪个shell来编写应用程序启动脚本,因为我知道这是一个跨平台的Java应用程序(几乎所有Linux发行版、MacOS、Solaris等等)。因此,我在这里添加了兼容性问题

请注意,我并不是问一般情况下“哪种shell最好使用”(在我看来可能没有意义:主观的,取决于需要),但我想知道,今天,哪种shell最有可能在大多数操作系统上可用(并且适合Java应用程序启动)

另外,我可以简单地使用shebang
#吗/bin/bash
要“使用bash”吗?(例如Korn shell的
#!/bin/ksh
)。如果此shell在此操作系统上不可用怎么办

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

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

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

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


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

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

然后,您应该限制shell脚本尽可能地遵守

但是,没有简单的方法来告诉脚本在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允许兼容的实现在那里提供一个不可移植的shell解释器。@jlliagre谢谢。因此,如果
/bin/sh
不能保证与POSIX兼容,那么应该使用哪种shebang?我在回复中解释了如何为特定平台获得它。谢谢。因此,如果
/bin/sh
不能保证与POSIX兼容,我应该使用哪个shebang?正如我所写的,您无法提前知道shebang应该是什么。最好的方法是使用脚本,在目标平台上安装脚本后进行设置/更新。好的,谢谢!(事实上,你在回答中解释了这一点,我的错!)不幸的是,你接受了一个没有抓住这一点的答案,特别是建议了一些在Solaris 10及更高版本上可能失败的问题。事实上,我正在等待解决方案的当前测试(
getconf PATH
)的结束。如果你的答案比另一个答案更能帮助我们,我当然不会接受第一个答案,也不会接受你的答案。我最初接受另一个问题,因为在安装后动态修改shebang对我来说似乎有点复杂或过分,但我可能错了,我们正在几个操作系统上测试这一点。谢谢回答得很好。如果可以,我会接受这两个答案(@Chris Dodd&@jlliagre)。对于未来的读者:我接受了jlliagre的回答,因为我认为使用
dash
测试脚本就足够了(不需要在POSIX模式下使用其他Shell进行测试),然后可能需要在一些派生Unix上动态更新shebang。