Qual é a diferença entre esses quatro comandos (fifo, substituição de processo, redirecionamento...)

Qual é a diferença entre esses quatro comandos (fifo, substituição de processo, redirecionamento...)

Meu objetivo é criar um servidor de eco simples usando ncum único arquivo fifo. Não estou procurando a melhor maneira de fazer isso, estou apenas tentando entender a semântica dos comandos a seguir (quando acontece o fork, por que, o que muda, por que os comandos se comportam de maneira diferente...).

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

Aqui estão os quatro comandos que menciono no título (supondo que já os tenha feito 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 fizessem a mesma coisa.

  1. O primeiro comando se comporta conforme o esperado, um servidor de eco simples que é encerrado quando o cliente encerra a conexão.
  2. Comporta-se como 1.
  3. Posso me 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.

Responder1

A chave aqui é que abrir um FIFO é uma operação de bloqueio. O openúnico retorna quando ambas as extremidades estiverem conectadas, ou seja, quando o fifo estiver aberto tanto para leitura quanto para escrita.

homem fifo (7)

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

No 1º caso, o shell se bifurca para executar o pipeline, portanto a abertura do fifo para leitura ( cat fifo) e a abertura do fifo para gravação ( > fifo) acontecem em processos separados, portanto acontecem de forma independente.

No 2º caso, a abertura para leitura e a abertura para escrita ( 3<>fifo) acontecem em uma única etapa.

No terceiro caso, <(cat fifo)expande para um nome de arquivo, por exemplo /dev/fd/42, . Então é como se você estivesse correndo nc -l localhost 8888 /dev/fd/42 > fifo. Você precisa de um extra <para que seja equivalente, por exemplo nc -l localhost 8888 < <(cat fifo) > fifo.

No 4º caso, o shell está tentando abrir o fifo para leitura ( < fifo) e abri-lo para escrita ( > fifo) como parte do mesmo processo. O shell faz um de cada vez, da esquerda para a direita. Então ele tenta abrir fifopara leitura e bloqueia para sempre, esperando que algo abra fifopara escrever. Acho que você descobrirá que, neste caso, ncnem sequer comecei e a porta nunca foi aberta para escuta.

informação relacionada