A chave aqui é que abrir um FIFO é uma operação de bloqueio. O open
só retorna quando as duas extremidades estiverem conectadas, ou seja, quando o fifo estiver aberto para leitura e escrita.
Normally, opening the FIFO blocks until the other end is opened also.
No primeiro caso, o shell se bifurca para executar o pipeline, portanto, abrir o fifo para leitura ( cat fifo
) e abrir o fifo para gravação ( > fifo
) ocorre em processos separados, portanto, independentemente.
No segundo caso, o aberto para leitura e aberto para escrita ( 3<>fifo
) acontece em uma única etapa.
No terceiro caso, <(cat fifo)
se expande para um nome de arquivo, por exemplo %código%. Então, é como se você estivesse executando /dev/fd/42
. Você precisa de um nc -l localhost 8888 /dev/fd/42 > fifo
extra para que seja equivalente, por exemplo, <
.
No quarto caso, o shell está tentando abrir o fifo para leitura ( nc -l localhost 8888 < <(cat fifo) > fifo
) e abri-lo para gravação ( < fifo
) como parte do mesmo processo. O shell faz um de cada vez, da esquerda para a direita. Então, ele tenta abrir > fifo
para leitura e bloqueia para sempre, esperando que algo abra fifo
para gravação. Eu acho que você vai achar que, neste caso, fifo
nunca sequer começou, e a porta nunca foi aberta para ouvir.