【问题标题】:why does my (ubuntu 11.10 bash 4.2.10, x86_64 ) named pipe get clogged?为什么我的 (ubuntu 11.10 bash 4.2.10, x86_64 ) 命名管道会堵塞?
【发布时间】:2012-02-08 18:50:23
【问题描述】:
第 1 步:我打开一个终端并输入
mkfifo mypipe
cat < mypipe
第 2 步:我打开另一个并输入:
for elem in {1..100} ; do echo "$elem" > mypipe ; done
打印出随机数量的数字,第一个脚本退出,第二个脚本挂起。
请分享智慧。 Ubuntu的错误?如果需要更多信息,请询问,我认为没有任何相关的 atm。
谢谢,
你们太棒了。
【问题讨论】:
标签:
bash
ubuntu
named-pipes
【解决方案1】:
命名管道的工作方式是,当写入进程关闭管道时,读取进程会收到一个 EOF。当cat 看到文件已结束时,它会停止读取并退出。这里 bash 似乎在循环中大部分时间都在重用打开的文件,而不是在每次运行时关闭并重新打开它。
为了确保文件在你可以这样写的时候打开和关闭:
(for elem in {1..100} ; do echo "$elem" ; done) > mypipe
要让cat 在每次运行中只输出一个数字,您必须使用程序/bin/echo 而不是内置的echo。这会强制 Bash 在每次循环运行时打开和关闭文件:
for elem in {1..100} ; do /bin/echo "$elem" > mypipe ; done
【解决方案2】:
如果有错误,那就是cat 面打印了多个。这是一个竞赛条件。发生的事情是cat 正在读取一行,然后才能读取 EOF(因为它们是单独的写入)echo 写入下一行,所以cat 得到了,等等。最终,它似乎,cat 在echo 重定向可以写入管道之前到达 EOF。如果您想一次将所有数字写入管道,请将重定向移至末尾:
for elem in {1..100} ; do echo "$elem" done > mypipe
或者更好,
seq 100 > mypipe
如果您希望cat 一次只能获得一个...我不太确定您如何轻松做到这一点(尽管我相信如果有必要我可以破解它)。