当我像这样运行 Centos 7 Docker Image
docker run -it centos:7 bash
运行使用Process Substitution的东西很好(正如预期的那样,因为 Bash 从一开始就支持 Process Substitution - 实际上是 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似乎是 Bash
/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
是的
bash
,当调用 as 时sh
,它以 POSIX 模式运行,禁用其所有仅 bash 功能。来自手册 -使用名称 sh 调用启用模式后,
posix
将不会启用进程替换等非标准功能。请参阅Bash POSIX 模式以查看其在该模式下运行的完整行为。从 shell 的 5.1 版开始,进程替换在 POSIX 模式下可用。
有些选项在 bash 的 POSIX 模式下被禁用。当
bash
被称为时被激活sh
。从 bash 手册页:但在版本
5.1
进程替换在 POSIX 模式下重新启用因此,对于当前版本(您正在使用现在已删除的自我回答中的 4.2),即使
bash
被称为sh
.是什么
/bin/sh
?我们在这里谈论的是Unix 遗产!一点历史:sh
是 Bourne Shell,它于 1979 年在 Unix 版本 7 中发布。它随着 Brian Kernighan 和 Rob Pike 的《Unix 编程环境》的出版而广受欢迎——这是第一本以教程形式将 shell 介绍为编程语言的商业出版书籍。ksh
最初由 David Korn 编写的 Korn shell 是基于原始 Bourne Shell 源代码,它是 Bourne shell 和csh
C 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 命令替换语法 $(...)。另外一点 - 在 Centos 7 上,
sh
是指向bash
. 没有单独的二进制文件sh
。bash
,dash
,busybox
和其他可能的 shell 可以检查它们开始时使用的命令行,并且会假装是其他东西,sh
如果它们是这样调用的,那么就像 plain 一样。这个符号链接让这种情况发生。你总是可以期待
/bin/sh
在那里,并成为一个基本的外壳。