CentOS 7:什么是/bin/sh?它看起来像 Bash,但又像是别的东西

CentOS 7:什么是/bin/sh?它看起来像 Bash,但又像是别的东西

当我像这样运行 Centos 7 Docker 镜像时

docker run -it centos:7 bash

运行一些正在使用的东西流程替代没问题(正如预期的那样,Bash 从一开始就支持进程替换 - 实际上是 Bash 1.4.x)。

例如:

while IFS= read -r test; do echo $test; done < <(cat anaconda-post.log)

但是当我切换到/bin/sh相同的代码不再起作用

/bin/sh
while IFS= read -r test; do echo $test; done < <(cat anaconda-post.log)
sh: syntax error near unexpected token `<'

虽然/bin/sh似乎是巴什

/bin/sh --version
GNU bash, version 4.2.46(2)-release (x86_64-redhat-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

但为什么流程替代不再有效呢?不过,其他非 POSIX 功能似乎也可以工作

echo ${PATH//:/ }
/usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin

答案1

是的,bash当被称为 时sh,会在 POSIX 模式下运行,禁用所有仅适用于 bash 的功能。从手册中 -使用名称 sh 调用

如果使用 sh 名称调用 Bash,它会尝试尽可能模仿 sh 历史版本的启动行为,同时也符合 POSIX 标准

$ ls -lrth /bin/sh
lrwxrwxrwx. 1 root root 4 Aug 26  2018 /bin/sh -> bash
$ /bin/bash -c 'set -o | grep posix'
posix           off
$ /bin/sh -c 'set -o | grep posix'
posix           on

启用posix模式后,将不会启用进程替换等非标准功能。看Bash POSIX 模式查看其在该模式下运行的完整行为。

从 shell 版本 5.1 开始,可以在 POSIX 模式下进行进程替换。

答案2

某些选项在 bash 的 POSIX 模式下被禁用。当bash被称为 as时,它会被激活sh。从 bash 手册页:

当作为 sh 调用时,bash 在读取启动文件后进入 posix 模式。

5.1在 POSIX 模式下重新启用版本进程替换

因此,对于当前版本(您正在使用现在已删除的自我答案中的 4.2),即使bash称为 as ,过程替换也可以工作sh

答案3

什么是/bin/sh?我们正在谈论Unix 遗产这里!一些历史:

sh是 Bourne Shell,它于 1979 年在 Unix 版本 7 中发布。它因 Brian Kernighan 和 Rob Pike 出版的《Unix 编程环境》而广受欢迎,这是第一本商业出版的书籍,介绍了 Unix 编程环境。作为教程形式的编程语言。

kshKorn shell 最初由 David Korn 编写,基于原始的 Bourne Shell 源代码,是 Bourne shell 和cshC shell 之间的中间道路。它的语法主要取自 Bourne shell,而其作业控制功能类似于 C shell。原始 Korn Shell 的功能被用作 POSIX shell 标准的基础。

bash是“Bourne Again SHell”。 Bash 语法是 Bourne shell 语法的超集。 Bash 语法包括从 Korn Shell 和 C shell 汲取的思想,例如命令行编辑、命令history、目录堆栈、$RANDOM 和 $PPID 变量以及 POSIX 命令替换语法 $(...)。

dash是“Debian Almquist shell”。它的首要任务是 POSIX 兼容性。

使用 bash 或 dash 的硬链接将sh其行为限制为 POSIX 标准。

答案4

另外一点 - 在 Centos 7 上,shbash.没有单独的二进制文件sh

[root@work ~]# ls -la `which sh`
lrwxrwxrwx. 1 root root 4 Jun 16  2020 /usr/bin/sh -> bash
[root@work ~]# ls -la /bin/sh
lrwxrwxrwx. 1 root root 4 Jun 16  2020 /bin/sh -> bash

[root@work ~]# rpm -qf /usr/bin/sh /bin/sh
bash-4.2.46-34.el7.x86_64

bashdashbusybox可能的其他 shell 可以检查它们启动时使用的命令行,并且会假装成其他东西,比如普通的(sh如果它们是这样调用的)。这个符号链接可以实现这一点。

你总是可以期待/bin/sh在那里,并且成为一个基本的外壳。

相关内容