如何在busybox shell脚本中以非阻塞模式刷新命名管道(FIFO)?

问题描述 投票:0回答:2

我尝试使用“cat”和“dd”命令来刷新 FIFO,这两个命令都会阻止操作。

以下是用于刷新的命令,

创建先进先出

mkfifo tmp.fifo

使用“cat”命令

cat tmp.fifo 

或者甚至使用带有 cat 命令的文件描述符,例如,

exec 200<> tmp/fifo; 
cat <&200 > /dev/null

使用“dd”命令

dd if=tmp.fifo of=/dev/null

注:

在“iflag”的帮助下,“dd”命令在 Linux PC 终端中运行良好(不会阻塞),

dd if=tmp/fifo iflag=nonblock of=/dev/null

(!) 但这不适用于 busybox 版本的

dd
。我怎样才能使用
busybox
实现它?

bash embedded-linux busybox
2个回答
4
投票

很容易检查这是否/如何可能,只需查看 busybox 源代码:busybox 代码库中的任何位置都不存在对

O_NONBLOCK
的引用。

因此:仅使用 busybox,这是不可能的。


现在,你可以做的事情(如果你的内核的行为是适当的——POSIX在这种模式下没有指定命名管道的行为,让它由实现定义)是用

O_RW
打开管道(所以它不需要写入器)并执行阻塞读取,另一个进程在超时后杀死它:

exec 5<>yourpipe
cat <&5 >/dev/null & cat_pid=$!
sleep 1
kill "$cat_pid"

这是一种丑陋、低效且可移植性值得怀疑的 hack——但无需添加额外的依赖项(Python、Perl、一个小小的 C 助手),这就是你所拥有的。


0
投票

答案取决于问题中

flush
的含义。

如果

flush
的含义是:

  • “清除缓冲区”:那么上面的答案就足够了。 它将从管道读取所有数据,输出到
    /dev/null
    • 或者,您可以使用
      /dev/null
      作为输入写入管道,这应该向从管道读取的程序发送
      EOF
      条件。
  • “快速刷新数据”(例如,对于命名管道和 FIFO 的行或无缓冲 IO):然后您应该评估
    stdbuf
    命令(最初来自 GNU coreutils)是否可以满足您的需要。

最后,查看以下有关 Linux 中 PIPE 缓冲的资源可能会有所帮助(因为本主题的细节可能相当深奥):

© www.soinside.com 2019 - 2024. All rights reserved.