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

时间:2016-06-07 07:44:40

标签: bash named-pipes

在bash 1中:

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

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

在bash 2中

$ </tmp/pipe

现在shell 1消失,它关闭,我的终端消失了。

为什么会这样?

在bash手册中有书面

  

命令替换$(cat文件)可以替换为   相当但更快的$(&lt; file)。

所以我正在尝试如果普通的“&lt; 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

修改

在看到初步评论和答案之后,我将添加一些澄清。

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

但我真正追求的是读者shell $ < /tmp/pipe场景编写器shell退出,但在阅读器shell中$ cat /tmp/pipe,编写器shell不会退出。为什么呢?

我看到我真的没有说出有问题和正文,并且应该提出另一个问题吗?

3 个答案:

答案 0 :(得分:1)

来自the pipe(7) manual page

  

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

当读取shell完成读取并关闭管道末端时,写入shell将收到SIGPIPE信号,如果它没有捕获它,那么shell将是终止。

答案 1 :(得分:0)

在手动签名$variable而非command prompt相关联。

尝试以下脚本:

1)

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

2)

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

两者都正常。

答案 2 :(得分:0)

键入< /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,然后退出。
  6. (另一种可能性是,如果从管道读取并尝试执行的命令导致错误,则shell 2退出。)

    另一方面,

    $(< file)是命令替换的特例。当bash看到它时,它只是从file本身读取,而不是产生cat进程并捕获其输出。