在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
的工作原理是连续读取其输入,并将读取的内容作为命令执行。
- 在shell 1中,
echo something > /tmp/pipe
打开管道进行写入,写入字符串,然后阻塞,直到有东西读取它。一旦echo
完成,它就会关闭管道的末端 < /tmp/pipe
打开管道进行读取,并将其连接到shell 2的标准输入- Shell 2从管道中读取(并尝试执行命令)
- 回到shell 1中,
echo
在从管道读取第二个shell之后被解除阻塞,完成。管道的写入端关闭 - 在管道的写入端关闭的情况下,shell 2在尝试读取另一个命令时将获得
SIGPIPE
,然后退出
(另一种可能性是,如果shell 2从管道中读取并试图执行的命令导致错误,则它将退出。)
另一方面,$(< file)
是命令替换的特殊情况。当bash
看到这一点时,它只是从file
本身读取,而不是生成cat
进程并捕获其输出。