echo 与 echo|cat 读取/写入 FIFO(管道)时的不同行为
Different behavior with echo vs echo|cat when reading to / writing from FIFOs (pipes)
我试图理解为什么 echo
在 bash 脚本中使用时表现不同于 echo "Hi"|cat
的原因,管道损坏
行为 :
echo
立即终止脚本
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 上的脚本(注意
KILL : <PID>
)
- 将一些示例行输入到终端 1 并验证
0
(成功退出代码)正在写入 /some/external/file
- 运行
kill -9 <PID>
来自终端 2
- 在terminal-1输入另一条采样线
-
- 如果
script_with_echo.sh
在步骤 1 中被执行,脚本立即终止(并且没有错误代码写入 /some/external/file
)
- 如果在步骤 1 中执行了
script_with_echo_cat.sh
,脚本将正常继续(并且对于每个后续示例行输入,错误代码 141(SIGPIPE
) 正在写入 /some/external/file
,这是预期的)
为什么会出现这种不同的行为?
why echo behaves differently than echo "Hi"|cat when used in a bash script
在 echo >&3
的情况下,当连接到第 3 个文件描述符的管道关闭时,bash 进程将被 SIGPIPE 杀死。这主要是因为 echo
是一个内置命令 - 它由 bash 本身执行,没有任何 fork()
ing.
在echo | cat >&3
的情况下,当连接到第3个文件描述符的管道关闭时,子进程cat
被SIGPIPE
杀死,在这种情况下父进程继续活下去,所以 Bash 可以处理退出状态。
比较 strace -ff bash -c 'mkfifo ii; cat <ii >/dev/null & pid=$! ; exec 3>ii ; kill $pid ; rm ii ; echo something >&3'
与 ....; /bin/echo something >&3'
。
我试图理解为什么 echo
在 bash 脚本中使用时表现不同于 echo "Hi"|cat
的原因,管道损坏
行为 :
echo
立即终止脚本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 上的脚本(注意
KILL : <PID>
) - 将一些示例行输入到终端 1 并验证
0
(成功退出代码)正在写入/some/external/file
- 运行
kill -9 <PID>
来自终端 2 - 在terminal-1输入另一条采样线
-
- 如果
script_with_echo.sh
在步骤 1 中被执行,脚本立即终止(并且没有错误代码写入/some/external/file
) - 如果在步骤 1 中执行了
script_with_echo_cat.sh
,脚本将正常继续(并且对于每个后续示例行输入,错误代码 141(SIGPIPE
) 正在写入/some/external/file
,这是预期的)
- 如果
为什么会出现这种不同的行为?
why echo behaves differently than echo "Hi"|cat when used in a bash script
在 echo >&3
的情况下,当连接到第 3 个文件描述符的管道关闭时,bash 进程将被 SIGPIPE 杀死。这主要是因为 echo
是一个内置命令 - 它由 bash 本身执行,没有任何 fork()
ing.
在echo | cat >&3
的情况下,当连接到第3个文件描述符的管道关闭时,子进程cat
被SIGPIPE
杀死,在这种情况下父进程继续活下去,所以 Bash 可以处理退出状态。
比较 strace -ff bash -c 'mkfifo ii; cat <ii >/dev/null & pid=$! ; exec 3>ii ; kill $pid ; rm ii ; echo something >&3'
与 ....; /bin/echo something >&3'
。