Quali sono le differenze tra questi quattro comandi (fifo, sostituzione del processo, reindirizzamento ...)


8

Il mio obiettivo è quello di creare un semplice server echo utilizzando nce un singolo fifo. Non sto cercando il modo migliore per farlo, sto solo cercando di capire la semantica dei seguenti comandi (quando si verifica il fork, perché, cosa cambia, perché i comandi si comportano diversamente ...).

Sto utilizzando Bash, quindi non sono sicuro se tutti i comandi funzionerà con un POSIX sho zsh, ksh...

Ecco i quattro comandi che sto citando nel titolo (supponendo che l'ho già fatto 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

Ora mi aspetto che i 4 comandi facciano la stessa cosa, perlomeno gli ultimi due facciano la stessa cosa.

  1. Il primo comando si comporta come previsto, un semplice server echo che si spegne quando il client chiude la connessione.
  2. Si comporta come 1.
  3. Posso connettermi al server, inviare dati, ma non ricevo mai nulla indietro. Quando chiudo la connessione client, il server si spegne.
  4. Impossibile connettersi al server, il server è in ascolto per sempre.

Risposte:


8

La chiave qui è che l'apertura di un FIFO è un'operazione di blocco. Gli openunici ritorni una volta che entrambe le estremità sono collegate, cioè una volta che il fifo è aperto sia per la lettura che per la scrittura.

man fifo (7)

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

Nel primo caso, la shell richiede l'esecuzione della pipeline, quindi l'apertura del fifo per la lettura ( cat fifo) e l'apertura del fifo per la scrittura ( > fifo) avvengono in processi separati, quindi in modo indipendente.

Nel secondo caso, l'apertura per la lettura e l'apertura per la scrittura ( 3<>fifo) avvengono in un unico passaggio.

Nel terzo caso, si <(cat fifo)espande in un nome file, ad es /dev/fd/42. Quindi è come se stessi correndo nc -l localhost 8888 /dev/fd/42 > fifo. È necessario un extra <affinché sia ​​equivalente, ad es nc -l localhost 8888 < <(cat fifo) > fifo.

Nel quarto caso, la shell sta provando ad aprire il fifo per reading ( < fifo) e aprirlo per writing ( > fifo) come parte dello stesso processo. La shell li fa uno alla volta, da sinistra a destra. Quindi cerca di aprirsi fifoper la lettura e si blocca per sempre, in attesa di qualcosa da aprire fifoper la scrittura. Penso che scoprirai che in questo caso ncnon è nemmeno mai stato avviato e la porta non è mai stata aperta per l'ascolto.


Oh sì, errore stupido in # 3, ma alla fine il risultato rimane lo stesso. Solo un'altra domanda che è più curiosità di ogni altra cosa, è il solo modo per aprire il fifo per r / w in un solo passo? E c'è un altro modo per forzare la shell a fork come in # 1? Grazie!
pippo

nc ... <>fifodovrebbe essere sufficiente. gnu.org/software/bash/manual/html_node/Redirections.html
Mikel

1
La shell si biforterà ogni volta che si utilizza una pipeline, una subshell o una sostituzione di processo.
Mikel,

2
Correzione, ne avrai bisogno nc ... <>fifo >&0, poiché si <>fifoapre fifoper leggere e scrivere su fd 0 e vogliamo che anche l'output vada lì.
Mikel,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.