linux – #!/ bin / sh vs#!/ bin / bash,实现最大的可移植性

我通常使用Ubuntu LTS服务器,从我理解的symlink / bin / sh到/ bin / dash.很多其他的发行版虽然symlink / bin / sh到/ bin / bash.

据我所知,如果脚本在顶部使用#!/ bin / sh,它可能无法在所有服务器上以相同的方式运行?

当人们想要在服务器之间实现这些脚本的最大可移植性时,是否建议使用哪种shell用于脚本?

解决方法

shell脚本大致有四个级别的可移植性(就shebang行而言):

>大多数可移植:使用#!/ bin / sh shebang并仅使用POSIX standard中指定的基本shell语法.这应该适用于几乎任何POSIX / unix / linux系统. (好吧,除了具有真正遗留Bourne shell的Solaris 10和更早版本之外,在POSIX之前不符合要求,比如/ bin / sh.)
>第二最便携:使用#!/ bin / bash(或#!/usr/bin/env bash)shebang line,并坚持使用bash v3功能.这适用于任何具有bash(在预期位置)的系统.
>第三最便携:使用#!/ bin / bash(或#!/usr/bin/env bash)shebang line,并使用bash v4功能.任何拥有bash v3的系统都会失败(例如macOS,出于许可的原因必须使用它).
>最不便携:使用#!/ bin / sh shebang并使用POSASH shell语法的bash扩展.对于除了bash for / bin / sh之外的任何系统(例如最近的Ubuntu版本),这将失败.不要这样做;这不仅仅是一个兼容性问题,它只是完全错误.不幸的是,这是很多人犯的错误.

我的建议:使用前三个中最保守的,提供脚本所需的所有shell功能.为了获得最大的可移植性,请使用选项#1,但根据我的经验,一些bash功能(如数组)非常有用,我将使用#2.

你可以做的最糟糕的事情是#4,使用错误的shebang.如果您不确定哪些功能是基本的POSIX,哪些是bash扩展,请坚持使用bash shebang(即选项#2),或者使用非常基本的shell(如Ubuntu LTS服务器上的dash)彻底测试脚本. Ubuntu wiki有一个good list of bashisms to watch out for.

关于Unix和Linux中的shell之间的历史和差异,有一些非常好的信息. Linux问题“What does it mean to be sh compatible?”和Stackoverflow问题“Difference between sh and bash”.

另外,请注意shell不是不同系统之间唯一不同的东西;如果你已经习惯了linux,你已经习惯了GNU命令,这些命令有很多非标准的扩展,你可能在其他unix系统上找不到(例如bsd,macOS).不幸的是,这里没有简单的规则,你只需要知道你正在使用的命令的变化范围.

可移植性方面最糟糕的命令之一是最基本的命令之一:echo.任何时候你使用它与任何选项(例如echo -n或echo -e),或在字符串中的任何转义(反斜杠)打印,不同的版本将做不同的事情.任何时候你想要打印一个没有换行的字符串,或者在字符串中使用转义字符串时,请使用printf(并了解它是如何工作的 – 它比echo更复杂). ps命令是also a mess.

另一个值得关注的一般事项是命令选项语法的最近/ GNUish扩展:旧(标准)命令格式是命令后跟选项(使用单个破折号,每个选项是单个字母),然后是命令参数.最近(通常是非便携式)变体包括长选项(通常用 – 引入),允许选项在参数之后,并使用 – 将选项与参数分开.

相关文章

文章浏览阅读1.8k次,点赞63次,收藏54次。Linux下的目录权限...
文章浏览阅读1.6k次,点赞44次,收藏38次。关于Qt的安装、Wi...
本文介绍了使用shell脚本编写一个 Hello
文章浏览阅读1.5k次,点赞37次,收藏43次。【Linux】初识Lin...
文章浏览阅读3k次,点赞34次,收藏156次。Linux超详细笔记,...
文章浏览阅读6.8k次,点赞109次,收藏114次。【Linux】 Open...