%3F.png)
Mi objetivo es crear un servidor de eco simple usando nc
un ú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 sh
o 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.
- El primer comando se comporta como se esperaba, un servidor de eco simple que se apaga cuando el cliente cierra la conexión.
- Se comporta como 1.
- Puedo conectarme al servidor, enviar datos, pero nunca recibo nada. Cuando cierro la conexión del cliente, el servidor se apaga.
- 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.
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 fifo
para leer y se bloquea para siempre, esperando que algo se abra fifo
para escribir. Creo que encontrará que en este caso nc
ni siquiera comenzó y el puerto nunca se abrió para escuchar.