为什么bash在写入命名管道时关闭

  • 本文关键字:管道 bash bash named-pipes
  • 更新时间 :
  • 英文 :


在bash 1:

$ mkfifo /tmp/pipe
$ echo 'something' > /tmp/pipe

现在它挂起并等待数据被读取。

在bash 2:

$ </tmp/pipe

现在1号外壳不见了,它关闭了,我的终端也不见了。

为什么会发生这种情况

在bash手册中有写

命令替换$(cat文件)可以替换为等价但更快的$(<file)。

所以我在试验普通的"<file"是否以类似于cat文件内容到终端的方式工作。

$ bash --version | head -1
GNU bash, version 4.3.11(1)-release (x86_64-pc-linux-gnu)
$ cat /proc/version
Linux version 3.16.0-71-generic (buildd@lgw01-46) (gcc version 4.8.2 (Ubuntu 4.8.2-19ubuntu1) ) #92~14.04.1-Ubuntu SMP Thu May 12 23:31:46 UTC 2016

编辑

在看到最初的评论和答案后,我将补充一些澄清。

我不关心不同的命令行语法。

但我真正想要的是,在阅读器外壳$ < /tmp/pipe场景中,编写器外壳退出,但在阅读器外壳中使用$ cat /tmp/pipe时,编写器壳不会退出。为什么?

我发现我真的没有在问题和身体中表达这一点,可能应该提出另一个问题?

来自pipe(7)手册页面:

如果引用管道读取端的所有文件描述符都已关闭,则write(2)将导致为调用进程生成SIGPIPE信号。

发生的情况是,当读取shell完成读取并关闭其管道末端时,写入shell将接收SIGPIPE信号,如果它没有捕获到信号,则shell将终止。

在手动标志中,$variable相连,而不是与command prompt相连。

尝试以下脚本:

1)

#!/bin/bash
echo $(< /tmp/pipe);

2)

#!/bin/bash
echo $(cat /tmp/pipe);

两者都能正常工作。

键入< /tmp/pipe时,将当前shell的标准输入连接到命名管道。bash的工作原理是连续读取其输入,并将读取的内容作为命令执行。

  1. 在shell 1中,echo something > /tmp/pipe打开管道进行写入,写入字符串,然后阻塞,直到有东西读取它。一旦echo完成,它就会关闭管道的末端
  2. < /tmp/pipe打开管道进行读取,并将其连接到shell 2的标准输入
  3. Shell 2从管道中读取(并尝试执行命令)
  4. 回到shell 1中,echo在从管道读取第二个shell之后被解除阻塞,完成。管道的写入端关闭
  5. 在管道的写入端关闭的情况下,shell 2在尝试读取另一个命令时将获得SIGPIPE,然后退出

(另一种可能性是,如果shell 2从管道中读取并试图执行的命令导致错误,则它将退出。)

另一方面,$(< file)是命令替换的特殊情况。当bash看到这一点时,它只是从file本身读取,而不是生成cat进程并捕获其输出。

相关内容

  • 没有找到相关文章