避免覆盖现有的命名管道

避免覆盖现有的命名管道

我有这个命令:

ql_receiver_lock_holder > "${my_named_pipe}"

如果命名管道已经存在,它会覆盖它吗?避免覆盖它的最好方法是简单地使用它:

ql_receiver_lock_holder >> "${my_named_pipe}"

答案1

重定向到命名管道不会删除管道,它会通过管道传递数据,或者如果没有从管道读取任何内容,则会阻塞。

这是使用命名管道的正常方式。您创建它,然后通过它发送数据。

答案2

>执行open()inO_WRONLY|O_TRUNK模式而>>执行open()inO_WRONLY|O_APPEND模式,但对于命名管道来说,这没有区别。

需要考虑 3 种不同的情况:

  1. 还没有进程打开 fifo 文件进行读取:那么open()(在命令执行之前由 shell 完成)将阻塞,直到某个进程打开该文件进行读取。
  2. 某些进程已经打开 fifo 文件进行读取,但还没有进行写入:那么我们open()将成功并实例化管道。然后,该命令将立即启动,并且能够写入数据将累积的管道,直到管道变满或某个进程读取另一端的内容。
  3. 管道已经被实例化(因为 fifo 文件已经打开用于读取和写入)。然后open()将返回一个 fd 到同一个管道(而不是实例化一个新管道)。这意味着我们的命令所做的写入将与写入管道的其他命令的写入交错。仅当小于该值PIPE_BUF(Linux 上为 4KiB)时,才保证写入是原子的。这与创建的常规管道没有什么不同pipe()

一种有所不同的打开模式是 O_RDWR(读+写),在 shell 中您可以使用<>运算符实现(1<>重定向 stdout,否则它会在 fd 0 (stdin) 上打开),在许多系统上,如果满足以下条件,它永远不会阻塞并实例化管道:尚未实例化。

相关内容