这四个命令有什么区别(fifo、进程替换、重定向...)

foo*_*foo 8 shell bash io-redirection process-substitution fifo

我的目标是使用nc和单个fifo. 我不是在寻找最好的方法来做到这一点,我只是想了解以下命令的语义(fork 何时发生,为什么,它发生了什么变化,为什么命令的行为不同......)。

我正在使用 Bash,所以我不确定所有命令是否都适用于 POSIXshzsh, ksh, ...

这是我在标题中提到的四个命令(假设我已经这样做了mkfifo fifo):

cat fifo | nc -l localhost 8888 > fifo
exec 3<> fifo && nc -l localhost 8888 <&3 >&3 && exec 3>&-
nc -l localhost 8888 <(cat fifo) > fifo
nc -l localhost 8888 < fifo > fifo
Run Code Online (Sandbox Code Playgroud)

现在我希望 4 个命令做同样的事情,至少最后两个命令做同样的事情。

  1. 第一个命令按预期运行,一个简单的回显服务器在客户端关闭连接时关闭。
  2. 表现得像 1。
  3. 我可以连接到服务器,发送数据,但我从来没有收到任何回复。当我关闭客户端连接时,服务器关闭。
  4. 无法连接到服务器,服务器永远监听。

Mik*_*kel 8

这里的关键是打开一个 FIFO 是一个阻塞操作。在open一旦FIFO是开放的读取和写入一次的两端只有回报连接,即。

人先入先出(7)

Normally, opening the FIFO blocks until the other end is opened also.
Run Code Online (Sandbox Code Playgroud)

在第一种情况下,shell 分叉以执行管道,因此打开 fifo 进行读取 ( cat fifo) 和打开 fifo 进行写入 ( > fifo) 发生在不同的进程中,因此独立发生。

在第二种情况下,读取打开和写入打开 ( 3<>fifo) 发生在一个步骤中。

在第三种情况下,<(cat fifo)扩展为文件名,例如/dev/fd/42. 所以这就像你在跑步nc -l localhost 8888 /dev/fd/42 > fifo。你需要一个额外<的它是等效的,例如 nc -l localhost 8888 < <(cat fifo) > fifo.

在第 4 种情况下,作为同一进程的一部分,shell 尝试打开 fifo 进行读取 ( < fifo) 并打开它进行写入 ( > fifo)。外壳一次一个,从左到右。所以它试图打开fifo读取,并永远阻塞,等待打开fifo写入。我想你会发现在这种情况下,nc甚至从来没有开始过,端口也从来没有打开过监听。

  • 每当您使用管道、子外壳或进程替换时,外壳都会派生。 (2认同)
  • 更正,您将需要 `nc ... &lt;&gt;fifo &gt;&amp;0`,因为 `&lt;&gt;fifo` 打开 `fifo` 以在 fd 0 上进行读写,并且我们希望输出也到那里。 (2认同)