Was ist der Unterschied zwischen diesen vier Befehlen (FIFO, Prozessersetzung, Umleitung…)

8

Mein Ziel ist es, einen einfachen Echoserver mit nceinem einzigen zu erstellen fifo. Ich suche nicht nach dem besten Weg, ich versuche nur, die Semantik der folgenden Befehle zu verstehen (wann passiert Fork, warum, was ändert sich, warum verhalten sich die Befehle anders ...).

Ich bin mit Bash, so dass ich nicht sicher bin , ob alle Befehle mit einem POSIX arbeiten shoder zsh, ksh, ...

Hier sind die vier Befehle, die ich im Titel erwähne (vorausgesetzt, ich habe es bereits getan 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

Jetzt würde ich erwarten, dass die 4 Befehle dasselbe tun, zumindest die beiden letzten, die dasselbe tun.

  1. Der erste Befehl verhält sich wie erwartet, ein einfacher Echoserver, der heruntergefahren wird, wenn der Client die Verbindung schließt.
  2. Benimmt sich wie 1.
  3. Ich kann eine Verbindung zum Server herstellen, Daten senden, aber ich erhalte nie etwas zurück. Wenn ich die Clientverbindung schließe, wird der Server heruntergefahren.
  4. Es kann keine Verbindung zum Server hergestellt werden. Der Server hört für immer zu.
foo
quelle

Antworten:

8

Der Schlüssel hier ist, dass das Öffnen eines FIFO eine Blockierungsoperation ist. Die openRückkehr erfolgt nur, wenn beide Enden verbunden sind, dh wenn das Fifo sowohl zum Lesen als auch zum Schreiben geöffnet ist.

Mann fifo (7)

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

Im ersten Fall gibt die Shell die Pipeline aus, sodass das Öffnen des Fifo zum Lesen ( cat fifo) und das Öffnen des Fifo zum Schreiben ( > fifo) in separaten Prozessen erfolgen, also unabhängig voneinander.

Im zweiten Fall erfolgt das Öffnen zum Lesen und Öffnen zum Schreiben ( 3<>fifo) in einem einzigen Schritt.

Im dritten Fall wird <(cat fifo)zu einem Dateinamen erweitert, z /dev/fd/42. Es ist also so, als würdest du rennen nc -l localhost 8888 /dev/fd/42 > fifo. Sie benötigen ein Extra, <damit es gleichwertig ist, z nc -l localhost 8888 < <(cat fifo) > fifo.

Im vierten Fall versucht die Shell, das FIFO zum Lesen ( < fifo) und zum Schreiben ( > fifo) als Teil desselben Prozesses zu öffnen . Die Shell macht sie einzeln von links nach rechts. Es versucht sich fifozum Lesen zu öffnen und blockiert für immer und wartet darauf, dass sich etwas zum fifoSchreiben öffnet . Ich denke, Sie werden feststellen, dass in diesem Fall noch ncnie begonnen wurde und der Port nie zum Abhören geöffnet wurde.

Mikel
quelle
Oh ja, dummer Fehler in # 3, aber am Ende bleibt das Ergebnis gleich. Nur eine andere Frage, die mehr Neugier als alles andere ist, ist exec die einzige Möglichkeit, das Fifo für R / W in einem einzigen Schritt zu öffnen? Und gibt es eine andere Möglichkeit, die Schale wie in # 1 zum Gabeln zu zwingen? Vielen Dank!
foo
nc ... <>fifosollte ausreichen. gnu.org/software/bash/manual/html_node/Redirections.html
Mikel
1
Die Shell teilt sich jedes Mal, wenn Sie eine Pipeline, eine Subshell oder eine Prozessersetzung verwenden.
Mikel
2
Korrektur, die Sie benötigen nc ... <>fifo >&0, da zum Lesen und Schreiben auf fd 0 <>fifogeöffnet fifowird und wir möchten, dass die Ausgabe auch dorthin geht.
Mikel