我试着用FIFO做些简单的事情:读几行,但不是一遍一遍,它出乎意料地“不起作用”。
这是可以的:
$ f=$(mktemp -u)
$ mkfifo $f
$ { seq 5 > $f; } &
[1] 2486
$ while read line; do echo $line; done < $f
1
2
3
4
5
[1]+ Done { seq 10 > $f; }但如果我试着逐个读行,第一读成功,第二读挂起。
$ { seq 5 > $f; } &
[1] 2527
$ read line < $f; echo $line
1
[1]+ Done { seq 5 > $f; }
$ read line < $f; echo $line
[hangs here...]有人能解释一下吗?为什么我不能一个接一个地看完所有的五行?剩下的数据怎么了?
我发现,如果我创建一个文件描述符来重定向FIFO,我可以逐行读取:
$ { seq 5 > $f; } &
[1] 2732
$ exec 3<$f
[1]+ Done { seq 5 > $f; }
$ read -u 3 line && echo $line || echo no more data
1
$ read -u 3 line && echo $line || echo no more data
2
$ read -u 3 line && echo $line || echo no more data
3
$ read -u 3 line && echo $line || echo no more data
4
$ read -u 3 line && echo $line || echo no more data
5
$ read -u 3 line && echo $line || echo no more data
no more data
$ exec 3<&-我还是不明白中间的情况。有人能解释吗?
版本信息:
$ bash --version
GNU bash, version 4.2.25(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
$ mkfifo --version
mkfifo (GNU coreutils) 8.13
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>.
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Written by David MacKenzie.发布于 2014-04-15 16:16:18
我想接下来会发生这样的事情:
$ read line < $f打开FIFO进行读取,读取一行,然后关闭FIFO。一旦读取器关闭FIFO,作者(seq 5 > $f)也会关闭。当您下一次打开FIFO时,没有人在这一点上给它写信,所以read阻塞。
对于while,FIFO是开放的,直到while命令完成,允许写入器向FIFO发送更多行。
您可以使用lsof -p $$来验证哪些文件在每个点都是打开的(而不是)。
发布于 2014-04-15 16:19:07
这里似乎有些关于FIFO的混淆。
当你说:
read line < $f它会打开FIFO,查找,阅读,并在关闭后完成它。不管你是读一行还是读整条数据都没关系。
因此,当您再次尝试阅读时,read一直在等待。
在等待的时候,试着说:
echo foo > $f你会注意到read是成功的。
如果您正在监视在这两种情况下正在进行的系统调用,您会发现第二个read正在等待从FIFO读取。
不知道你想在这里完成什么,但是你的观察基本上是沿着预期的方向进行的。
https://stackoverflow.com/questions/23088620
复制相似问题