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

为什么在写入命名管道时关闭bash?,bash,named-pipes,Bash,Named Pipes,在bash 1中: $ mkfifo /tmp/pipe $ echo 'something' > /tmp/pipe $ </tmp/pipe 现在它挂起并等待读取数据 在bash 2中: $ mkfifo /tmp/pipe $ echo 'something' > /tmp/pipe $ </tmp/pipe 编辑 在看到最初的评论和答案后,我将补充一点澄清 我不关心不同的命令行语法 但我真正想要的是,在reader shell$

在bash 1中:

$ mkfifo /tmp/pipe
$ echo 'something' > /tmp/pipe
$ </tmp/pipe
现在它挂起并等待读取数据

在bash 2中:

$ mkfifo /tmp/pipe
$ echo 'something' > /tmp/pipe
$ </tmp/pipe
编辑

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

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

但我真正想要的是,在reader shell
$
场景中,writer shell退出,但在reader shell中,writer shell不退出。为什么?

我明白了,我真的没有在问题和正文中表达这一点,可能应该提出另一个问题?

来自:

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


发生的情况是,当读取外壳完成读取并关闭其管道末端时,写入外壳将接收到
SIGPIPE
信号,如果未捕捉到该信号,则外壳将终止。

在手动符号中
$
变量连接
而不是
命令提示符

请尝试以下脚本:

(一)


两者都能正常工作。

当您键入
时,将当前shell的标准输入连接到命名管道
bash的工作原理是不断地从输入中读取内容,并将其作为命令执行

  • 在shell 1中,
    echo something>/tmp/pipe
    打开管道进行写入,写入字符串,然后阻塞,直到有人读取它。一旦
    echo
    完成,它将关闭其管道末端
  • 打开管道进行读取,并将其连接到shell 2的标准输入
  • Shell 2读取管道(并尝试执行命令)
  • 回到shell 1,在从管道读取第二个shell后,
    回音
    解除阻塞,完成。管道的写入端关闭
  • 当管道的写入端关闭时,shell 2在尝试读取另一个命令时将获得一个
    SIGPIPE
    ,然后退出
  • (另一种可能性是,如果shell 2从管道读取并尝试执行的命令导致错误,则shell 2将退出。)


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

    我想他们不会问这个问题。我想他们会问,如果使用
    @123的问题标题“为什么在写入命名管道时关闭bash?”表明不是这样,为什么它不输出任何内容。在这种情况下,它是一个明显的副本,应该标记为一个。这是正确的。如果执行
    (echo something>/tmp/pipe),您可以看到它;echo$?
    。这将打印
    141
    ,即
    128+13
    13
    SIGPIPE
    。因此子shell被SIGPIPE杀死。为什么“cat/tmp/pipe”不会导致SIGPIPE写入,而“他没有键入
    $
    ,他只是在命令提示符下显示。是的。我的意思是
    $
    中的
    $
    ,不在
    $中,这与问题有什么关系,这就是为什么
    回送某个东西的过程会消失的原因?我不知道它是什么意思,但我解释说在文档中有使用
    $(
    。总结:cat/tmp/pipe-在屏幕上打印
    某物
    ,$(cat/tom/pipe)-作为命令执行
    某物
    ,$(某物
    更快。我认为
    是不正确的命令。
    $(
    是命令替换的特例;
    不是
    cat文件的通用替换。Writer shell(1)在完成写入时获取SIGPIPE()。读卡器shell(2)不退出。
    
    #!/bin/bash
    echo $(cat /tmp/pipe);