Quais são as diferenças entre esses quatro comandos (fifo, substituição de processos, redirecionamento…)

8

Meu objetivo é criar um servidor de eco simples usando nc e um único fifo . Eu não estou procurando a melhor maneira de fazer isso, estou apenas tentando entender a semântica dos seguintes comandos (quando acontece, por que, o que muda, por que os comandos se comportam de maneira diferente ...). / p>

Estou usando o Bash, então não tenho certeza se todos os comandos funcionarão com um POSIX sh ou zsh , ksh , ...

Aqui estão os quatro comandos que estou mencionando no título (assumindo que eu já fiz 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

Agora eu esperaria que os 4 comandos fizessem a mesma coisa, pelo menos os dois últimos fazendo a mesma coisa.

  1. O primeiro comando se comporta como esperado, um servidor de eco simples que é desligado quando o cliente fecha a conexão.
  2. se comporta como 1.
  3. Eu posso conectar ao servidor, enviar dados, mas nunca recebo nada de volta. Quando fecho a conexão do cliente, o servidor é desligado.
  4. Não é possível conectar-se ao servidor, o servidor escuta para sempre.
por foo 14.06.2014 / 14:56

1 resposta

8

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.

homem fifo (7)

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.

    
por 14.06.2014 / 18:51