为什么在写入命名管道时关闭bash?
在bash 1中:为什么在写入命名管道时关闭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$
$ 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);