为什么带有 /bin/bash 的脚本可以工作,而 /bin/sh 不行?

Wol*_*lfy 2 bash scripts

我的朋友问我为什么这两个简单的脚本在两个 shell 中都不起作用:

测试文件“abc.txt”:

aaa
111
bbb
111
ccc
111
ddd
Run Code Online (Sandbox Code Playgroud)

脚本#1 (a):

#!/bin/sh
while read -r line ; do
    echo "Processing $line"
done < <(grep 111 abc.txt)
Run Code Online (Sandbox Code Playgroud)

输出:

./a: line 4: syntax error near unexpected token `<'
./a: line 4: `done < <(grep 111 abc.txt)'
Run Code Online (Sandbox Code Playgroud)

脚本#2 (b):

#!/bin/bash
while read -r line ; do
    echo "Processing $line"
done < <(grep 111 abc.txt)
Run Code Online (Sandbox Code Playgroud)

输出:

Processing 111
Processing 111
Processing 111
Run Code Online (Sandbox Code Playgroud)

我在我的机器上检查了 bash 和 sh,如果我理解正确,这是同一回事。

/bin/sh 只是指向 /bin/bash 的链接:

-rwxr-xr-x  1 root root 938736 May 10  2012 bash
lrwxrwxrwx. 1 root root      4 Feb 13 10:20 sh -> bash
Run Code Online (Sandbox Code Playgroud)

有人可以解释我的区别在哪里吗?

kir*_*iri 6

这是因为 Bash 在$0is时表现不同sh

来自Bash 的行为 [Bash Hackers Wiki]

SH模式

当 Bash 在 SH 兼容模式下启动时,它会尝试尽可能模仿历史版本的启动行为sh,同时也符合 POSIX® 标准。读取的配置文件是/etc/profileand ~/.profile,如果它是登录 shell。

如果它不是登录 shell,则评估环境变量 ENV 并将生成的文件名作为启动文件的名称。

读取启动文件后,Bash 进入POSIX(r) 兼容模式(用于运行,而不是用于启动!)

Bash 在以下情况sh下以兼容模式启动:

  • 中的基本文件名 argv[0]sh(注意亲爱的超级聪明的 Linux 用户....../bin/sh可能链接到 /bin/bash,但这并不意味着它的作用像 /bin/bash

更多信息可以在Bash 参考手册:Bash POSIX Mode 中找到,特别是:

  • 进程替换不可用。

这就是您的sh脚本失败的原因,因为<(..)语法使用了进程替换。