这个脚本:
#!/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"
将工作,因为echo
并cat
同时运行。
在 Linux 上,你可以摆脱:
exec 3<> "$tmppipe" 4< "$tmppipe"
echo test >&3
exec 3>&-
cat <&4
这是可行的,因为管道上的 read+write open
( <>
) 在 Linux 上不会阻塞,而且因为test\n
by 的输出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
并可以完成。