为什么 sh 有一个指向 dash 或 bash 的符号链接?

为什么 sh 有一个指向 dash 或 bash 的符号链接?

我发现 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 做功课。我想就这个问题得到一些专家的意见。

  1. 当使用 sh 调用时,Bash 在读取启动文件后进入 POSIX 模式。但这些启动文件是什么?
  2. 所以关键是,如果 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 进行对比,例如cshksh

然而,POSIX 标准化了 POSIX 的行为sh,并且在现代开源操作系统上,通常sh实际上是其他一些实现,并且它仅具有提供 POSIX 行为的模式。例如,在 FreeBSD 上,我们将其ash称为sh;在 OpenBSD 上,shksh是同一个程序,在 Linux 上,您经常会发现bashdashas sh(尽管 Debian 允许许多其他程序,包括zshmkshposh和可能的其他程序)。

在这种情况下,确实,无论调用什么 shell 都可以完成sh所需的工作,sh因为这些系统上没有独立的sh程序。它只是提供 POSIX 行为的一种模式。

在该 POSIX 模式下,如果该环境变量不存在,则读取的启动文件是登录 shell 的/etc/profile和以及交互式 shell$HOME/.profile所指向的文件的内容。$ENV不调用特定于 Shell 的文件。

相关内容