【问题标题】:Difference of interpretation of operator <<< between bash and zshbash和zsh对运算符<<<的解释差异
【发布时间】:2017-11-24 09:59:49
【问题描述】:

在zsh中,

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

将打印

Hello World

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

World

我的解释是,在 zsh 中 cat 将在标准输入上打开第一个文件描述符(第一个“-”选项),读取管道“Hello”,然后关闭标准输入,然后以某种方式重新打开它(第二个“-”选项),然后读取此处的字符串“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

cat 似乎只是忽略了它的第二个参数。

请任何 bash/zsh 的大师来启发我?有没有一种通用的方法可以将流与字符串连接起来而没有任何中间文件,或者如果可能的话,使用 here-document ?

【问题讨论】:

    标签: linux bash zsh


    【解决方案1】:

    其实这和 cat 的第二个- 参数无关。

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

    会有同样的结果。

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

    引用手册:

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

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

    【讨论】:

      【解决方案2】:

      您可以在命令是您想要的命令的地方执行此操作,例如echo

      echo "Hello " | COMMAND "$(cat -)World"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-07-28
        • 1970-01-01
        • 2017-03-23
        • 1970-01-01
        • 2015-06-17
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多