¿Cuál es la diferencia entre esos cuatro comandos (fifo, sustitución de procesos, redirección...)?

¿Cuál es la diferencia entre esos cuatro comandos (fifo, sustitución de procesos, redirección...)?

Mi objetivo es crear un servidor de eco simple usando ncun único archivo fifo. No estoy buscando la mejor manera de hacerlo, simplemente estoy tratando de entender la semántica de los siguientes comandos (cuándo ocurre la bifurcación, por qué, qué cambia, por qué los comandos se comportan de manera diferente...).

Estoy usando Bash, así que no estoy seguro de si todos los comandos funcionarán con POSIX sho zsh,, ksh...

Aquí están los cuatro comandos que menciono en el título (suponiendo que ya lo hice 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

Ahora esperaría que los 4 comandos hicieran lo mismo, al menos los dos últimos hicieran lo mismo.

  1. El primer comando se comporta como se esperaba, un servidor de eco simple que se apaga cuando el cliente cierra la conexión.
  2. Se comporta como 1.
  3. Puedo conectarme al servidor, enviar datos, pero nunca recibo nada. Cuando cierro la conexión del cliente, el servidor se apaga.
  4. No puedo conectarme al servidor, el servidor escucha para siempre.

Respuesta1

La clave aquí es que abrir un FIFO es una operación de bloqueo. El openúnico retorno es una vez que ambos extremos están conectados, es decir, una vez que el FIFO está abierto tanto para lectura como para escritura.

hombre quince(7)

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

En el primer caso, el shell se bifurca para ejecutar la canalización, por lo que abrir el quince para leer ( cat fifo) y abrir el quince para escribir ( > fifo) ocurren en procesos separados, por lo que suceden de forma independiente.

En el segundo caso, la apertura para lectura y la apertura para escritura ( 3<>fifo) ocurren en un solo paso.

En el tercer caso, <(cat fifo)se expande a un nombre de archivo, por ejemplo /dev/fd/42. Entonces es como si estuvieras corriendo nc -l localhost 8888 /dev/fd/42 > fifo. Necesita un extra <para que sea equivalente, por ejemplo nc -l localhost 8888 < <(cat fifo) > fifo.

En el cuarto caso, el shell intenta abrir el quince para leer ( < fifo) y abrirlo para escribir ( > fifo) como parte del mismo proceso. El caparazón los hace uno a la vez, de izquierda a derecha. Así que intenta abrirse fifopara leer y se bloquea para siempre, esperando que algo se abra fifopara escribir. Creo que encontrará que en este caso ncni siquiera comenzó y el puerto nunca se abrió para escuchar.

información relacionada