【问题标题】:What are the differences between fish shell and bash when handling named pipes?处理命名管道时,fish shell 和 bash 有什么区别?
【发布时间】:2021-09-17 01:49:41
【问题描述】:

在fish shell中执行这些命令时

$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer

命令挂起。
如果我通过echo "" &gt; answer 写信给answer。然后nc 恢复并开始正确收听。
如果,相反我CTRL-C挂了进程,下面是留言:

^C<W> fish: An error occurred while redirecting file 'answer'
open: Interrupted system call

另一方面,在 bash 中,执行时:

$ mkfifo answer
$ nc -vv -l -k -p 8001 <answer | tee -a answer
Listening on localhost 8001

命令挂起并直接开始收听。

fish 和 bash 中发生了什么不同的情况来解释这种不同的行为?

【问题讨论】:

  • 除了荒谬的回答之外,我还要指出您实际上不能依赖 bash 行为;或任何其他 POSIX shell AFAICT。打开 FIFO 进行读取将阻塞,直到进程打开它进行写入。 &lt;answer 在 bash 中打开块,但对您来说并不明显,因为它发生在子进程中。

标签: bash named-pipes fish


【解决方案1】:

主要区别在于fish在父shell中在fork之前打开重定向文件,而bash在子进程中在fork之后打开重定向文件。

当您打开命名管道进行读取时,打开调用将阻塞,直到有相应的写入器(反之亦然)。您的管道同时包含读取器和写入器,但要求相应的打开调用在子进程中并行发生。在鱼中nc 在文件打开之前无法启动,因此会出现死锁。

一种解决方法是安排子进程自行打开文件,而不是使用重定向。例如,这将避免死锁:

cat answer | nc -vv -k -l -p 8001  | tee -a answer

fish 之所以如此,是因为它也使用线程,这限制了您可以在分叉子项中执行的操作。

【讨论】:

    猜你喜欢
    • 2011-11-03
    • 2011-11-12
    • 2015-11-07
    • 2010-12-07
    • 2018-08-25
    • 2017-02-17
    • 1970-01-01
    • 2021-05-08
    • 1970-01-01
    相关资源
    最近更新 更多