Por que esse script canalizado não funciona?

2
#!/bin/bash
rm out
mkfifo out
nc -l 8080 < out | while read line
do
    echo hello > out   
    echo $line
done

Se eu navegar para o IP da máquina em que esse script está sendo executado (usando a porta 8080), esperaria ver a palavra 'hello' e, em seguida, na máquina que está executando o script, esperaria que ele emitisse linhas de o pedido.

No entanto, nada acontece. O navegador não recebe resposta e nada é enviado para o terminal do servidor.

Por que não funciona e o que posso modificar para que funcione? Eu quero mantê-lo para tubos simples, eu não quero usar a substituição de processos ou qualquer coisa assim.

    
por Cameron Ball 19.08.2014 / 07:00

1 resposta

1

O redirecionamento < out faz com que o canal nomeado seja aberto para leitura. Isso bloqueia, desde que nenhum processo tenha o tubo aberto para gravação. Enquanto isso, o lado direito do pipeline está bloqueando no comando read , aguardando que nc (que ainda não foi iniciado) exiba algo pelo canal. É um deadlock .

Para permitir que o script continue, verifique se o canal nomeado está aberto para gravação e para leitura independente. Por exemplo:

nc -l 8080 < out | while read line
do
    echo hello >&3
    echo "$line"
done 3>out

ou

nc -l 8080 < out | {
  exec 3>out
  while read line
  do
    echo hello >&3
    echo "$line"
  done
}

Observe que algo como isto não funcionaria, porque nc veria que sua entrada é fechada após a leitura de 0 bytes e gravações subseqüentes bloqueariam a espera para o canal nomeado ser aberto novamente para leitura:

nc -l 8080 < out | {
  : >out
  while read line
  do
    echo hello >out
    echo "$line"
  done
}
    
por 20.08.2014 / 02:40