什么是 Linux 中的 POSIX 兼容模式?

Sid*_*ril 6 command-line bash emulation

书上说:

在 POSIX 兼容模式下,bash 将模拟sh

这是什么意思?简单的外行术语中的仿真是什么意思?

ter*_*don 11

这不是 Linux 的东西,而是 bash 的东西。Bash 只是众多 shell 之一。Bash 是“Bourne again shell”并作为原始 Bourne Shell 的替代品发布sh

POSIX 是一组标准,用于定义符合 POSIX 的系统应该如何工作。可以在此处找到 POSIX shell 标准。Bash 具有许多不存在的功能,sh并且实际上不是符合 POSIX 的 shell。

--posix就是提供该选项的原因。如man bash(强调我的)中所述:

如果使用名称 sh 调用 bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准。当作为交互式登录 shell 或带有 --login 选项的非交互式 shell 调用时,它首先尝试按顺序从 /etc/profile 和 ~/.profile 读取和执行命令。--noprofile 选项可用于禁止此行为。 当作为一个名为 sh 的交互式 shell 被调用时,bash 查找变量 ENV,如果它被定义,则扩展它的值,并使用扩展的值作为要读取和执行的文件名。由于作为 sh 调用的 shell 不会尝试从任何其他启动文件读取和执行命令,因此 --rcfile 选项无效. 使用名称 sh 调用的非交互式 shell 不会尝试读取任何其他启动文件。当作为 sh 调用时,bash 在读取启动文件后进入 posix 模式。

当 bash 在 posix 模式下启动时,与 --posix 命令行选项一样,它遵循启动文件的 POSIX 标准。在这种模式下,交互式 shell 扩展 ENV 变量,并从名称为扩展值的文件中读取和执行命令。不会读取其他启动文件。

这意味着如果您运行shbash --posix来启动交互式 shell,您的~/.bahsrc文件将被忽略,而是$ENV读取保存为(如果有)的文件。为了说明,我已经添加echo "read .bashrc"到我的~/.bashrc

$ bash
read .bashrc  ## message was printed, ~/.bashrc was read
$ sh
sh-4.3$       ## no message printed, ~/.bashrc was not read
Run Code Online (Sandbox Code Playgroud)

如果我现在设置$ENV

$ export ENV="~/.bashrc"
$ sh
read .bashrc
Run Code Online (Sandbox Code Playgroud)

重要说明:Ubuntu 已选择/bin/sh/bin/dash. Dash 是另一种外壳,实际上是符合 POSIX 的外壳。这意味着为了观察我上面描述的行为,您需要使用不同的sh1。在 Ubuntu 上,您需要创建一个名为的文件sh,该文件是指向/bin/bash以下内容的符号链接:

$ ln -s /bin/bash ~/sh
Run Code Online (Sandbox Code Playgroud)

您现在sh在您的主目录中有一个名为的文件。用它来演示我上面解释的差异:

$ ls -l ~/sh
lrwxrwxrwx 1 terdon terdon 9 May  2 14:03 /home/terdon/sh -> /bin/bash
$ ~/sh
read .bashrc
Run Code Online (Sandbox Code Playgroud)

1 实际上,行为看起来好像是一样的,~/.bashrc会被忽略,但这只是因为dash不是,bash并且~/.bashrc无论如何都没有阅读特定于 bash 的业务。但是,dash也会忽略,$ENV因此您需要使用链接/bin/bash才能看到。

  • @wlad 是的,当然。这个答案中的所有内容都应该仍然相关。毕竟才三年半。 (2认同)