![为什么 sh 有一个指向 dash 或 bash 的符号链接?](https://linux22.com/image/191533/%E4%B8%BA%E4%BB%80%E4%B9%88%20sh%20%E6%9C%89%E4%B8%80%E4%B8%AA%E6%8C%87%E5%90%91%20dash%20%E6%88%96%20bash%20%E7%9A%84%E7%AC%A6%E5%8F%B7%E9%93%BE%E6%8E%A5%EF%BC%9F.png)
我发现 sh 是 bash 的符号链接
lrwxrwxrwx 1 root root 4 May 9 15:23 /bin/sh -> bash
我试图寻找一个原因,然后我发现bash 是 sh 的一个实现并且可以表现得像 sh 或 POSIX。因此,带有 #!/bin/sh 的脚本由 bash 调用,并尝试模仿 sh 的行为。还有其他实现,例如 dash、csh 等。在阅读时这个答案当使用 /bin/sh 调用时,bash 在读取启动文件后会转至 POSIX 模式。我对 shell 没有太多经验,但正如这些答案所指出的:在某些系统中默认没有 sh,而 bash 或任何其他 shell 正在为 sh 做功课。我想就这个问题得到一些专家的意见。
- 当使用 sh 调用时,Bash 在读取启动文件后进入 POSIX 模式。但这些启动文件是什么?
- 所以关键是,如果 bash 在我的系统中执行 sh 的工作,那么这是否意味着我的系统中没有 sh,并且所有带有 sh 的脚本都由 bash 或 sh 指向的任何其他 shell 调用。
答案1
当使用 sh 调用时,Bash 在读取启动文件后进入 POSIX 模式。但这些启动文件是什么?
启动文件还取决于它是否启动sh
。
在正常模式下,作为交互式 shell:如果是登录 shell,则为 // 的第一个;如果
/etc/profile
不是登录shell,则为 just。~/.bash_profile
~/.bash_login
~/.profile
~/.bashrc
在
sh
模式下:/etc/profile
如果~/.profile
是登录 shell;以及环境变量$ENV
指向的任何内容(如果是交互的)。特别是,它不会~/.bash*
在sh
模式下读取文件。
具体细节请参阅手册,这并不简单:6.2 Bash 启动文件
所以关键是,如果 bash 在我的系统中执行 sh 的工作,那么这是否意味着我的系统中没有 sh,并且所有带有 sh 的脚本都由 bash 或 sh 指向的任何其他 shell 调用。
我不太确定问题是什么,或者当 Bash 执行 sh 的工作时另一个 shell 会是什么。但无论如何,如果/bin/sh
指向/bin/bash
(或者是 Bash 的另一个副本),那么所有使用 hashbang 的脚本#!/bin/sh
和以system()
C 中的库调用开头的命令都将使用 Bash 运行。但这没关系,因为 Bash 能够很好地兼容这些用途。
另请注意,它csh
属于不同的系列,并且与 POSIX sh 不兼容。
答案2
在最初的 Unix 系统上,sh
是具有特定行为的特定程序。它经常与后来出现的其他 shell 进行对比,例如csh
和ksh
。
然而,POSIX 标准化了 POSIX 的行为sh
,并且在现代开源操作系统上,通常sh
实际上是其他一些实现,并且它仅具有提供 POSIX 行为的模式。例如,在 FreeBSD 上,我们将其ash
称为sh
;在 OpenBSD 上,sh
和ksh
是同一个程序,在 Linux 上,您经常会发现bash
或dash
as sh
(尽管 Debian 允许许多其他程序,包括zsh
、mksh
、posh
和可能的其他程序)。
在这种情况下,确实,无论调用什么 shell 都可以完成sh
所需的工作,sh
因为这些系统上没有独立的sh
程序。它只是提供 POSIX 行为的一种模式。
在该 POSIX 模式下,如果该环境变量不存在,则读取的启动文件是登录 shell 的/etc/profile
和以及交互式 shell$HOME/.profile
所指向的文件的内容。$ENV
不调用特定于 Shell 的文件。