【问题标题】:Different behavior with echo vs echo|cat when reading to / writing from FIFOs (pipes)从 FIFO(管道)读取/写入时,echo 与 echo|cat 的不同行为
【发布时间】:2021-09-12 19:40:00
【问题描述】:

我试图理解为什么 echo 在 bash 脚本中使用时与 echo "Hi"|cat 的行为不同且管道损坏的原因

行为

  1. echo 立即终止脚本
  2. echo "Hi"|cat 管道终止,但脚本继续

示例重现步骤

script_with_echo.sh

#!/bin/bash
mkfifo ii
cat<ii >/dev/null & echo "KILL : $!"
exec 3>ii
rm ii
while true; do read LINE; echo "$LINE" >&3; echo "$?">/some/external/file;done

script_with_echo_cat.sh

#!/bin/bash
mkfifo ii
cat<ii >/dev/null & echo "KILL : $!"
exec 3>ii
rm ii
while true; do read LINE; echo "$LINE"|cat>&3; echo "$?">/some/external/file;done
  1. 在终端 1 上运行脚本(注意 KILL : &lt;PID&gt;
  2. 向终端 1 输入一些示例行并验证 0(成功退出代码)正在写入 /some/external/file
  3. 从终端 2 运行 kill -9 &lt;PID&gt;
  4. 在终端 1 上输入另一条样本行
    • 如果 script_with_echo.sh 在第 1 步中被执行,脚本会立即终止(并且不会向 /some/external/file 写入错误代码)
    • 如果 script_with_echo_cat.sh 在步骤 1 中被执行,脚本会正常继续(并且对于每个后续的示例行输入,错误代码 141 (SIGPIPE) 将被写入 /some/external/file,这是预期的)

为什么会出现这种不同的行为?

【问题讨论】:

    标签: bash shell pipe pipeline named-pipes


    【解决方案1】:

    为什么 echo 在 bash 脚本中使用时的行为与 echo "Hi"|cat 不同

    echo &gt;&amp;3 的情况下,当管道连接到第三个文件描述符关闭时,bash 进程被 SIGPIPE 杀死。这主要是因为echo 是一个内置命令 - 它由 bash 本身执行,没有任何 fork()ing。

    echo | cat &gt;&amp;3的情况下,当连接到第3个文件描述符的管道关闭时,子进程catSIGPIPE杀死,在这种情况下父进程继续存在,因此Bash可以处理退出状态。

    比较 strace -ff bash -c 'mkfifo ii; cat &lt;ii &gt;/dev/null &amp; pid=$! ; exec 3&gt;ii ; kill $pid ; rm ii ; echo something &gt;&amp;3'....; /bin/echo something &gt;&amp;3'

    【讨论】:

    • 我也有类似的想法,但是which echo 在我的系统上输出/bin/echo,bash 是否使用内置函数?
    • @MadhuchhandaMandal,使用type echo,而不是which echowhich 对 shell 内置函数、shell 函数、别名等一无所知;作为一个外部命令本身,它检查 PATH,所以如果某些东西既作为 shell 内置命令又作为外部命令存在,which 将只知道外部命令形式。
    • @MadhuchhandaMandal, ...顺便说一句,如果你来自 zsh,which 是一个内置函数,这可能是你认为它可以看到 shell 内部状态的地方。不过,这是 zsh 独有的;我所知道的其他任何地方都是外部命令。
    • @CharlesDuffy 完全正确!! type which 现在澄清了 :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 2018-11-28
    • 1970-01-01
    • 2014-04-24
    • 2021-03-17
    相关资源
    最近更新 更多