在一些答案下,我看到建议避免在答案中使用 shell 特定命令的评论。
我如何知道所有 shell 中都存在哪些命令、运算符等?有标准清单吗?
man builtins
给出命令列表。这些是我可以在适用于所有 shell 的可移植 shell 脚本中使用的唯一命令吗?- 内置可以是特定于 shell 的吗?
- Linux 的标准与其他 Unix 的标准有何不同?
- 语法呢?标点符号、运算符等在某些 shell 中可以不同吗?
答案1
格雷格的维基有一个关于为 Dash 调整 bash 脚本的帖子这指出了很多“bashism”——非标准但属于 bash 一部分的额外功能。避免这些攻击有助于使您的脚本对不同环境更加友好。这特别回答了您的一些问题。例如,是的,有些运算符是不同的(例如==
),但有一个标准的 Posix 集应该在所有环境中工作。
如需更全面的阅读,您可以查看POSIX标准,所有 shell 都应遵守。特别是“壳牌与公用事业”卷。
我发现比 shell 差异更具挑战性的是命令差异。许多 Linux 系统都有 GNU find
,但如果您正在编写可移植脚本,请不要依赖自己的脚本man find
,因为有很多系统都带有 BSD find
,它们具有不同的功能集。如果您正在为 busybox 编写脚本,您会发现不同的版本具有完全不同的nc
s。当我将脚本部署到不同的环境时,这些总是让我感到困惑。
如需额外阅读有关良好 shell 脚本编写实践的内容,David Pashley 的博客上还有一个很好的资源:编写健壮的 Bash Shell 脚本
另外,请确保您阅读吉尔斯本网站的答案和评论。他有很多关于确保使用可移植代码的技巧。
答案2
在特定 shell 中编写 shell 脚本意味着安装了该 shell。唯一的标准是拥有csh
并sh
安装在所有 Unix 变体上。因此,如果您希望脚本在 Solaris、*BSD 和 GNU 上运行,那么您必须将其编写在 Bourne shell 中。
然而,大多数 Unix 命令在不同的实现下具有不同的语法 - 看看ps
在 Solaris、FreeBSD 和 GNU 下 - 因此,根据您使用的工具,您的脚本可能无法移植。 shell 安装在哪里也很重要。是/bin/bash
/usr/bin/bash
、、/usr/local/bin/bash
还是其他地方?
我不知道有任何定义 shell 的标准。看一下RC或者 http://192.220.96.201/es/es-usenix-winter93.html`">es 用于奇怪的非标准 shell。但是,这些似乎仍然符合一些常见的想法。