为什么文件重定向到命名管道和从命名管道重定向不工作,但管道到 cat 呢?

Raz*_*van 9 pipe socket fifo

这是一个简单的 Unix 回显服务器,使用 nc:

mkfifo fifo
cat fifo | nc -k -l 4458 -v | cat >fifo
Run Code Online (Sandbox Code Playgroud)

(基于

正如我所见,数据流的工作原理如下:

fifo (my named pipe)
 |
 | (using cat)
 |
 v
nc
 |
 | (using cat)
 |
 v
fifo 
Run Code Online (Sandbox Code Playgroud)

这里有一个问题:为什么这不起作用?

nc -k -l 4458 -v >fifo <fifo
Run Code Online (Sandbox Code Playgroud)

你会发现,如果试图telnetlocalhost4458,你会得到一个“连接被拒绝”的错误。

meu*_*euh 10

这是因为 netcat 命令还没有启动!尝试打开 fifo 进行输入时,shell 将阻塞。尝试

strace cat >fifo <fifo
Run Code Online (Sandbox Code Playgroud)

你什么也看不到。而是使用,例如,

nc -k -l 4458 -v <>fifo >&0
Run Code Online (Sandbox Code Playgroud)

它打开fifo以作为stdin进行读写,然后将其复制到stdout。


跟踪完整的 bash 命令显示读取和写入的打开都没有返回(直到相反的打开完成):

$ strace -f -e open bash -c 'nc -k -l 4458 -v  >fifo <fifo'
...
Process 3631 attached
[pid  3631] open("fifo", O_WRONLY|O_CREAT|O_TRUNC, 0666

$ strace -f -e open bash -c 'nc -k -l 4458 -v  <fifo >fifo'
...
Process 3684 attached
[pid  3684] open("fifo", O_RDONLY
Run Code Online (Sandbox Code Playgroud)

man 3 mkfifo:打开 FIFO 以正常读取阻塞,直到其他进程打开相同的 FIFO 进行写入,反之亦然。