首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在shell脚本中使用mkfifo

在shell脚本中使用mkfifo
EN

Stack Overflow用户
提问于 2014-04-15 15:50:01
回答 2查看 8.4K关注 0票数 5

我试着用FIFO做些简单的事情:读几行,但不是一遍一遍,它出乎意料地“不起作用”。

这是可以的:

代码语言:javascript
复制
$ 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; }

但如果我试着逐个读行,第一读成功,第二读挂起。

代码语言:javascript
复制
$ { seq 5 > $f; } &
[1] 2527
$ read line < $f; echo $line
1
[1]+  Done                    { seq 5 > $f; }
$ read line < $f; echo $line
[hangs here...]

有人能解释一下吗?为什么我不能一个接一个地看完所有的五行?剩下的数据怎么了?

我发现,如果我创建一个文件描述符来重定向FIFO,我可以逐行读取:

代码语言:javascript
复制
$ { 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<&-

我还是不明白中间的情况。有人能解释吗?

版本信息:

代码语言:javascript
复制
$ 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.
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-04-15 16:16:18

我想接下来会发生这样的事情:

$ read line < $f打开FIFO进行读取,读取一行,然后关闭FIFO。一旦读取器关闭FIFO,作者(seq 5 > $f)也会关闭。当您下一次打开FIFO时,没有人在这一点上给它写信,所以read阻塞。

对于while,FIFO是开放的,直到while命令完成,允许写入器向FIFO发送更多行。

您可以使用lsof -p $$来验证哪些文件在每个点都是打开的(而不是)。

票数 6
EN

Stack Overflow用户

发布于 2014-04-15 16:19:07

这里似乎有些关于FIFO的混淆。

当你说:

代码语言:javascript
复制
read line < $f

它会打开FIFO,查找,阅读,并在关闭后完成它。不管你是读一行还是读整条数据都没关系。

因此,当您再次尝试阅读时,read一直在等待。

在等待的时候,试着说:

代码语言:javascript
复制
echo foo > $f

你会注意到read是成功的。

如果您正在监视在这两种情况下正在进行的系统调用,您会发现第二个read正在等待从FIFO读取。

不知道你想在这里完成什么,但是你的观察基本上是沿着预期的方向进行的。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23088620

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档