Alexander Mills Asked: 2019-06-05 09:25:48 +0800 CST2019-06-05 09:25:48 +0800 CST 2019-06-05 09:25:48 +0800 CST 如何在不等待的情况下使用命名管道 772 如果命名管道中没有任何内容,我会这样做: cat my_named_pipe 它将等到数据到达。如果没有要读取的数据,是否可以使用标志立即退出?或者也许是我可以使用的 cat 以外的命令? 我也试过: read val < "$my_named_pipe"; 但这也会等待下一个数据块——如果 fifo 为空,我不想等待。 tail cat 2 个回答 Voted Best Answer Stéphane Chazelas 2019-06-05T09:40:48+08:002019-06-05T09:40:48+08:00 为了防止cat在没有任何作家的情况下挂起(在这种情况下,它是 fifo 的打开,而不是从中读取,挂起),您可以执行以下操作: cat 0<> "$my_named_pipe" <"$my_named_pipe" 第一个重定向以读+写模式打开,在大多数系统上,即使没有写入器也没有读取器,它也不会阻塞并实例化管道。然后第二个打开(这次是只读的)不会阻塞,因为现在至少有一个写入器(本身)。 仅在最新版本的0ksh93 中才需要,其中默认 fd<>从 0 更改为 1。 此外,在 中,当shell 内置ksh93时,这将不起作用,例如在调用之前或之后调用时,(我猜)ksh93 将 stdin 的前一个目标保存在单独的文件描述符上,这将保持管道打开。您可以通过编写它来解决这个问题:catksh93/opt/ast/bin/bin$PATHbuiltin cat<"$my_named_pipe" cat 3<> "$my_named_pipe" <"$my_named_pipe" 3<&- (您也可能会争辩说更清楚地传达了意图) 请注意,<>在管道上也会将其他读取器解锁到 fifo。 如果有一些作家,cat仍然必须阅读他们的所有输出并等到他们关闭管道的末端。您可以在非阻塞模式下打开管道,例如使用 GNUdd的: dd bs=64k if="$my_named_pipe" iflag=nonblock status=noxfer 只要管道中有一些数据,它就会从管道中读取,并退出 dd: error reading 'fifo': Resource temporarily unavailable 当没有更多的阅读器时出错,并且没有解锁其他阅读器,但这意味着如果它们写入管道的速度比你(dd)读取它的速度慢,你可能会错过一些作者的输出。 另一种方法可能是在一段时间内没有输入时超时,例如使用socat's-T选项: socat -u -T1 - - 0<> "$my_named_pipe" <"$my_named_pipe" 如果一秒钟内没有任何东西从管道中流出,它将退出。 borizzzzz 2019-10-26T09:58:50+08:002019-10-26T09:58:50+08:00 很简单的事情是cat在读取 fifo 后立即终止,无论是否有数据。您可以使用 执行此操作timeout,如下所示: timeout 2 cat my_named_pipe 上面,timeout在强制 cat 终止之前等待两秒钟。如果运行时命名管道中有缓冲的内容cat,它将被打印到标准输出。 也许不是最干净的解决方案,但可以完成工作。 希望能帮助到你。
为了防止
cat
在没有任何作家的情况下挂起(在这种情况下,它是 fifo 的打开,而不是从中读取,挂起),您可以执行以下操作:第一个重定向以读+写模式打开,在大多数系统上,即使没有写入器也没有读取器,它也不会阻塞并实例化管道。然后第二个打开(这次是只读的)不会阻塞,因为现在至少有一个写入器(本身)。
仅在最新版本的
0
ksh93 中才需要,其中默认 fd<>
从 0 更改为 1。此外,在 中,当shell 内置
ksh93
时,这将不起作用,例如在调用之前或之后调用时,(我猜)ksh93 将 stdin 的前一个目标保存在单独的文件描述符上,这将保持管道打开。您可以通过编写它来解决这个问题:cat
ksh93
/opt/ast/bin
/bin
$PATH
builtin cat
<"$my_named_pipe"
(您也可能会争辩说更清楚地传达了意图)
请注意,
<>
在管道上也会将其他读取器解锁到 fifo。如果有一些作家,
cat
仍然必须阅读他们的所有输出并等到他们关闭管道的末端。您可以在非阻塞模式下打开管道,例如使用 GNUdd
的:只要管道中有一些数据,它就会从管道中读取,并退出
当没有更多的阅读器时出错,并且没有解锁其他阅读器,但这意味着如果它们写入管道的速度比你(
dd
)读取它的速度慢,你可能会错过一些作者的输出。另一种方法可能是在一段时间内没有输入时超时,例如使用
socat
's-T
选项:如果一秒钟内没有任何东西从管道中流出,它将退出。
很简单的事情是
cat
在读取 fifo 后立即终止,无论是否有数据。您可以使用 执行此操作timeout
,如下所示:上面,
timeout
在强制 cat 终止之前等待两秒钟。如果运行时命名管道中有缓冲的内容cat
,它将被打印到标准输出。也许不是最干净的解决方案,但可以完成工作。
希望能帮助到你。