我看到使用了两种类型的代码:
#!/usr/bin/sh
和:
#!/user/bin/bash
我在网上搜索过这个问题,大家的看法各不相同。我在大多数网站上看到的解释都说 比sh
更古老bash
,而且没有真正的区别。
有人知道它们之间的区别吗?你能给我一个实际的例子来说明何时使用其中一个而不是另一个吗?
答案1
bash
是 的超集sh
,即,sh
您可以在 中执行的所有操作bash
。
Bash 具有更多功能(分支、内置命令、数组),使脚本更容易编写。一些较新的 *nix 具有/bin/sh
以下链接:/bin/bash
完整解释一下这里有一个教程
答案2
传统上,/bin/sh 应该是原始的 Bourne shell,它没有历史记录或命令行编辑,也没有作业控制。
在过去的 15 年左右的时间里,大多数 Unix 都安装了 POSIX shell,或者至少安装了 ksh 或 bash(它们非常类似于 POSIX),但 /bin/sh 中仍然有功能较为有限的 shell
这样做的原因是,期望使用旧sh
命令的旧 shell 脚本仍能正常工作。由于、和
等字符对 bash 具有特殊含义,因此使用这些字符(未对其进行转义)的旧 shell 脚本可能会失败。 (Bourne shell 会按字面意思理解,而 bash 会将其解释为重复上一个命令 ( ),后跟括号扩展)。{
}
!
!!{1,2}
!!
然而在 Linux 上,该sh
命令几乎总是只是一个指向 的链接bash
,具有所有相同的功能。
答案3
sh 既可以表示 Bourne shell,也可以表示 /bin/sh,后者是大多数现代平台上其他一些(符合 POSIX 标准的)shell。“POSIX shell”是抽象的POSIX 定义的 shell,由 POSIX 模式下的 bash 实现,默认情况下由 ksh 或 dash 实现。/bin/sh 有时也称为 POSIX shell,因为它是大多数平台上符合 POSIX 的 shell。原始的 Bourne shell 不是 POSIX shell。
bashref 有一个列表bash 和 Bourne shell 之间的区别.man bash
有一个列表在 POSIX 模式下调用 bash 时发生更改。
/bin/sh 不是 OS X 上的符号链接或硬链接,但它的大小几乎与 /bin/bash 相同:
$ ls -li /bin/{ba,}sh
29631757 -r-xr-xr-x 1 root wheel 1333920 Jul 26 01:52 /bin/bash
29631758 -r-xr-xr-x 1 root wheel 1334000 Jul 26 01:52 /bin/sh
男子猛击:
如果使用名称 sh 调用 bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。
除此之外,对 Bourne shell 的模仿还相当有限。bash +B
(Bourne) 实际上会禁用括号扩展等功能。
$ sh
$ echo {a,b}
a b
$ echo $BASH_VERSION
3.2.48(1)-release
$ bash +B
$ echo {a,b}
{a,b}
但即使你禁用 POSIX 模式,echo 的echo -e
默认行为如下:
$ sh
$ shopt -uo posix
$ echo '1\b2'
2
/bin/sh 已打开Ubuntu,所以一些巴什主义在 OS X 上可以使用 /bin/sh,但不能在 Ubuntu 上使用。
如果您确实想为(类似于)原始 Bourne shell 编写脚本,#!/usr/bin/env bash +B
那么您可以使用。
我认为为 bash 编写脚本比避免使用不属于 POSIX 规范或 Bourne shell 的功能或使用其他 shell 测试所有内容更容易。
答案4
在许多系统上,尤其是在 Solaris 上,bash 是动态链接的,而 sh 是静态链接的。这可能带来安全威胁,因此 root 用户应仅使用 /bin/sh 作为 shell(如果您需要以 root 身份登录)。