我怎么知道写入命名管道是否会阻塞?

Mat*_*ice 7 bash fifo

仅当它已经有一个读者时,我才想写入命名管道。目前,我正在使用timeout来检测写入管道的尝试是否被阻止,如下所示:

#! /usr/bin/env bash
rm -f pipe
mkfifo pipe
sleep 5

timeout 1 bash -c "echo Hello > pipe"

if [[ $? == 0 ]]
then
    echo Somebody got our message
else
    echo Nobody read from pipe, so we didn\'t send a message
fi
Run Code Online (Sandbox Code Playgroud)

这有效。如果我tail -f pipe在睡眠期间在一个单独的终端中,我会收到一条消息,如果没有,我会收到另一条消息。但是有更好的方法吗?理想情况下,这将是不依赖超时的东西。

Sté*_*las 6

如果你想写入管道,只有当有一些进程打开它进行读取时,你才能以非阻塞模式打开它进行写入。

使用 GNU dd

echo Hello | dd oflag=nonblock of=pipe status=none &&
  echo message has been sent
Run Code Online (Sandbox Code Playgroud)

如果没有阅读器,您将收到 ENXIO 的错误消息(类似No such device or address in English)。

请注意,如果管道已满(如果有读取器,但当前未读取并且已写入 64KiB 之类的内容),它也会失败(带有EWOULDBLOCK/ EAGAINResource 暂时不可用)。

另请注意,如果不适合,则可能不会写入所有消息。如果删除status=none,您将看到写入了多少。