为什么这个带有 FIFO 管道的脚本没有终止?

为什么这个带有 FIFO 管道的脚本没有终止?

这个脚本:

#!/bin/bash
tmppipe=/tmp/temppipe
mkfifo $tmppipe
echo "test" > $tmppipe
cat $tmppipe
exit

不会终止。我假设该cat命令正在等待EOF来自管道的命令;我该如何发送?

答案1

不,它是

echo test > "$tmppipe" # BTW, you've got the quotes in the wrong places

那个挂着。更准确地说,它是 shell 在运行之前打开管道进行写入echo

pipe是进程间通信机制,它们将在运行的进程之间使用同时。这里,open(WR_ONLY)( >) 将阻塞,直到另一个进程执行open读模式。

echo test > "$tmppipe" &
cat < "$tmppipe"

将工作,因为echocat同时运行。

在 Linux 上,你可以摆脱:

exec 3<> "$tmppipe" 4< "$tmppipe"
echo test >&3
exec 3>&-
cat <&4

这是可行的,因为管道上的 read+write open( <>) 在 Linux 上不会阻塞,而且因为test\nby 的输出echo足够小以适合管道,所以您可以按顺序执行写入和读取。

它不适用于较大的输出,例如:

exec 3<> "$tmppipe" 4< "$tmppipe"
seq 100000 >&3
exec 3>&-
cat <&4

因为seq会填满管道(当前版本的 Linux 中为 64kiB)并阻塞,直到其他进程从该管道读取数据,这永远不会发生,因为在完成cat之前不会运行。seq

注意:

echo test 1<> "$tmppipe"
cat < "$tmppipe"

也不起作用,因为echo命令行将打开管道,写入测试,然后关闭管道(然后系统将销毁它,因为不再有文件描述符打开)。因此,下一个cat命令行将尝试实例化一个新管道(并阻塞,直到有东西打开 fifo 文件进行写入)。

答案2

结果答案很明显 - 管道被 锁定echo,并且永远不会到达猫!

管道不存储数据。当进程尝试写入管道时,写入无法完成,直到管道的另一端附加了某些内容以读取它。

解决这个特定示例的一种方法是使用

echo "test" > $tmppipe &

使写入过程在后台运行。这样,当脚本继续执行时,它会一直等待,直到到达cat并可以完成。

相关内容