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