运算符的解释差异<<<在bash和zsh之间

时间:2017-11-24 09:59:49

标签: linux bash zsh

在zsh,

echo -n "Hello " | cat - - <<< "World"

将打印

Hello World

但是在bash中,同样的命令会打印

World

我的解释是在zsh cat中将在stdin上打开第一个文件描述符(第一个' - '选项),读取管道“Hello”,然后关闭stdin,然后以某种方式重新打开它(第二个' - '选项),然后阅读here-string“World”,然后将它们加入“Hello World”。

但我不明白bash会发生什么。 strace给了我奇怪的结果:

zsh $> echo -n "Hello " | strace cat - - <<< "World"
strace: Unknown pid: 7841
Process 7844 detached

bash $> echo -n "Hello " | strace cat - - <<< "World"
...
read(0, "World\n", 65536)               = 6
write(1, "World\n", 6)                  = 6
read(0, "", 65536)                      = 0
fstat(0, {st_mode=S_IFREG|0600, st_size=6, ...}) = 0
fadvise64(0, 0, 0, POSIX_FADV_SEQUENTIAL) = 0
read(0, "", 65536)                      = 0
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
猫似乎忽略了它的第二个论点。

请bash / zsh的任何大师来启发我吗?是否有一种通信方式来连接一个没有任何中间文件的字符串的流,或者,如果可能的话,这里是一个文档?

2 个答案:

答案 0 :(得分:4)

实际上这与cat的第二个-参数无关。

echo -n "Hello " | cat - <<< "World"

会有相同的结果。

区别在于multios zsh选项。您可以检查unsetopt multios zsh之后的行为方式与bash相同。

引用手册:

  

如果用户尝试打开文件描述符以便多次读取,则shell会打开文件描述符作为进程的管道,该进程按照指定的顺序将所有指定的输入复制到其输出,类似于cat,前提是设置了MULTIOS选项。

因此,在您的示例中,shell将连接管道和此处的数据并将其连接到cat的输入。

答案 1 :(得分:0)

您可以在命令是您想要的命令echo

的情况下执行此操作
echo "Hello " | COMMAND "$(cat -)World"