什么是sh?
sh(或Shell 命令语言)是POSIX standard 描述的一种编程语言。它有很多实现(ksh88,Dash,...)。 Bash 也可以被视为sh 的实现(见下文)。
因为sh 是规范,而不是实现,所以/bin/sh 是大多数POSIX 系统上实际实现的符号链接(或硬链接)。
什么是 Bash?
Bash 最初是一个与sh 兼容的实现(尽管它比 POSIX 标准早了几年),但随着时间的推移,它已经获得了许多扩展。许多这些扩展可能会改变有效 POSIX shell 脚本的行为,因此 Bash 本身并不是一个有效的 POSIX shell。相反,它是 POSIX shell 语言的一种方言。
Bash 支持--posix 开关,这使其更符合 POSIX。如果调用为 sh,它还会尝试模仿 POSIX。
sh = bash?
很长一段时间以来,/bin/sh 在大多数 GNU/Linux 系统上都指向 /bin/bash。因此,忽略两者之间的差异几乎是安全的。但这种情况最近开始发生变化。
/bin/sh 不指向 /bin/bash(其中一些甚至可能不存在 /bin/bash)的系统的一些流行示例是:
- 现代 Debian 和 Ubuntu 系统,默认将
sh 符号链接到 dash;
-
Busybox,通常在 Linux 系统启动期间作为
initramfs 的一部分运行。它使用ash shell 实现。
-
BSD 系统,通常是任何非 Linux 系统。 OpenBSD 使用
pdksh,KornShell 的后代。 FreeBSD 的sh 是原始Unix Bourne shell 的后代。 Solaris 有自己的 sh 很长一段时间都不符合 POSIX 标准;可从Heirloom project 获得免费实施。
您如何找出/bin/sh 在您的系统上指向的内容?
复杂之处在于/bin/sh 可能是符号链接或硬链接。如果是符号链接,portable 的解决方法是:
% file -h /bin/sh
/bin/sh: symbolic link to bash
如果是硬链接,试试
% find -L /bin -samefile /bin/sh
/bin/sh
/bin/bash
事实上,-L 标志涵盖了符号链接和硬链接,
但这种方法的缺点是不便携——
POSIX does not require find 支持-samefile 选项,尽管GNU find 和FreeBSD find 都支持它。
社邦线
最终,由您决定使用哪一个,将 «shebang» 行写为脚本的第一行。
例如
#!/bin/sh
将使用sh(以及所指向的任何内容),
#!/bin/bash
如果可用,将使用/bin/bash(如果不可用,则会失败并显示错误消息)。当然,你也可以指定另一个实现,例如
#!/bin/dash
使用哪个
对于我自己的脚本,我更喜欢sh,原因如下:
- 它是标准化的
- 更简单,更容易学习
- 它可以跨 POSIX 系统移植——即使它们碰巧没有
bash,它们也必须有sh
使用bash 也有好处。它的特性使编程更方便,类似于用其他现代编程语言进行编程。这些包括范围局部变量和数组之类的东西。 Plain sh 是一种非常简约的编程语言。