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


8

我的目标是使用nc和创建一个简单的echo服务器fifo。我并不是在寻找最好的方法,我只是想了解以下命令的语义(何时发生派生,为什么,它发生了什么变化,为什么命令表现不同...)。

我使用bash,所以我不知道如果所有的命令都将使用POSIX工作shzshksh...

这是我在标题中提到的四个命令(假设我已经做过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

现在,我希望这4个命令可以执行相同的操作,至少最后两个命令可以执行相同的操作。

  1. 第一个命令的行为符合预期,一个简单的回显服务器在客户端关闭连接时将关闭。
  2. 行为像1。
  3. 我可以连接到服务器,发送数据,但是我什么也收不到。当我关闭客户端连接时,服务器关闭。
  4. 无法连接到服务器,服务器将永远监听。

Answers:


8

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

男士fifo(7)

Normally, opening the FIFO blocks until the other end is opened also.

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

在第二种情况下,阅读开放和写作开放(3<>fifo)一步完成。

在第3种情况下,<(cat fifo)扩展为文件名,例如/dev/fd/42。就像您在跑步nc -l localhost 8888 /dev/fd/42 > fifo。您需要额外的费用<才能使它等效,例如 nc -l localhost 8888 < <(cat fifo) > fifo

在第4种情况下,外壳程序尝试打开fifo进行读取(< fifo),然后打开fifo 进行写入(> fifo),这是同一过程的一部分。Shell一次从左到右执行一次操作。因此,它尝试打开fifo以供阅读,并永久阻止,以等待打开fifo以供写入。我想您会发现在这种情况下,nc甚至从未启动,并且端口从未打开过进行监听。


哦,是的,#3愚蠢的错误,但最后结果还是一样。另一个比其他问题更具好奇心的问题是,exec是一步打开rfo的fifo的唯一方法吗?还有其他方法可以迫使外壳像#1中那样分叉吗?谢谢!
2014年


1
只要您使用管道,子Shell或进程替换,该Shell就会派生。
Mikel 2014年

2
校正,你需要nc ... <>fifo >&0的,因为<>fifo打开fifo阅读和FD 0写,我们要输出去那里了。
Mikel 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.