bash 在 shell 脚本中使用 mkfifo

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/23088620/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 10:12:38  来源:igfitidea点击:

using mkfifo in a shell script

bashshellmkfifo

提问by glenn Hymanman

I was trying to do something simple with a FIFO: read the lines, but not all at once, and it unexpectedly "did not work".

我试图用 FIFO 做一些简单的事情:读取行,但不是一次全部读取,并且出乎意料地“不起作用”。

This is OK:

还行吧:

$ 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; }

But if I try reading lines one-by-one, the first read succeeds and the 2nd read hangs.

但是,如果我尝试逐行阅读,第一次读取成功,第二次读取挂起。

$ { seq 5 > $f; } &
[1] 2527
$ read line < $f; echo $line
1
[1]+  Done                    { seq 5 > $f; }
$ read line < $f; echo $line
[hangs here...]

Can someone explain this? Why can't I read all 5 lines one-by-one? What happened to the rest of the data?

有人可以解释一下吗?为什么我不能一一阅读所有 5 行?其余数据发生了什么变化?



I discovered I can read line-by-line if I create a file descriptor to redirect the FIFO:

我发现如果我创建一个文件描述符来重定向 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<&-

I still don't understand the middle scenario. Can anyone explain?

我仍然不明白中间场景。谁能解释一下?



Version info:

版本信息:

$ 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.

回答by mustaccio

I guess what happens is this:

我想会发生什么:

$ read line < $fopens the FIFO for reading, reads one line, then closes the FIFO. Once the reader closes the FIFO on its side, the writer (seq 5 > $f) also closes. When you open the FIFO next time nobody writes to it at that point, so the readblocks.

$ read line < $f打开 FIFO 进行读取,读取一行,然后关闭 FIFO。一旦读取器关闭其一侧的 FIFO,写入器 ( seq 5 > $f) 也会关闭。当您下次打开 FIFO 时,此时没有人向其写入数据,因此read阻塞。

With the whilethe FIFO is open for reading until the whilecommand finishes, allowing the writer to send more lines to the FIFO.

whileFIFO处于打开状态以供读取,直到while命令完成,允许写入器向 FIFO 发送更多行。

You can use lsof -p $$to verify what files are (not) open at each point.

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

回答by devnull

It seems that there is some confusion about FIFOhere.

FIFO这里似乎有些混乱。

When you say:

当你说:

read line < $f

it'd open the FIFO, seek, read, and be done with it after closing. It doesn't matter whether you read a line or the entire data.

它会打开 FIFO,查找、读取并在关闭后完成。读取一行数据还是整个数据都没有关系。

So when you attempt to read again, the readkeeps waiting.

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

While it's waiting, try saying:

在等待的时候,试着说:

echo foo > $f

and you'd notice that the readis successful.

你会注意到这read是成功的。

If you were monitoring the system calls being made in both the cases, you'd observe that the second readis waiting to read from the FIFO.

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

Not sure what you're trying to accomplish here but your observation is pretty much along expected lines.

不确定您要在这里完成什么,但您的观察几乎与预期一致。