Isso parece ser um bug em nc
. O comando nc
usa a chamada do sistema poll
para aguardar até que a entrada seja recebida de stdin
ou do soquete.
Quando um pacote UDP foi enviado para uma porta UDP fechada no terminal de recebimento, uma mensagem de erro é enviada de volta. A chamada poll
retornará esse status para o comando nc
, mas nc
na verdade não processará o erro. Em vez disso, nc
volta a chamar a chamada do sistema poll
novamente, que retorna imediatamente devido ao erro que ainda está sendo enfileirado no soquete.
Isso poderia ter sido um loop infinito, onde nc
consumiria todo o tempo de CPU que poderia fazer sem ser útil.
No entanto, dura apenas até a próxima mensagem ser recebida em stdin
. Neste ponto, poll
retorna os dois status para nc
, que processa os dados de stdin
. Agora nc
tentará gravar os dados de stdin
no soquete. A tentativa de gravar no soquete entregará o erro na fila para nc
. A mensagem de erro de gravação fará com que nc
termine.
Isso deixa você com um cano quebrado (isto é, um cano com um gravador, mas nenhum leitor). Qualquer tentativa de gravar no pipe acionará um sinal SIGPIPE
e se o processo não for eliminado pelo SIGPIPE
de um erro da chamada de gravação.
date
não está processando SIGPIPE
, então date
é eliminado. Portanto, o loop continua, mas sempre que date
é eliminado ao tentar gravar no canal em que o leitor está ausente há muito tempo.
O que pode ser feito
Embora o nc
de loop na chamada do sistema poll
sem entregar o erro seja definitivamente um bug, corrigir esse bug não seria necessariamente suficiente para atender às suas necessidades. Simplesmente terminar assim que o erro for retornado de poll
pode ser considerado o bug correto para nc
. Poderíamos imaginar um recurso adicional, em que nc
poderia ser instruído a continuar após um erro se receber uma sinalização específica.
Mas você poderia contornar o problema simplesmente reiniciando o nc em um loop como este:
while sleep 1 ; do date ; done | while true ; do nc -u localhost 514 ; done
O bug que causa uso excessivo da CPU periodicamente em nc
ainda estaria lá. Além disso, a combinação desse bug e a solução alternativa podem fazer com que a primeira mensagem após a porta de destino seja reaberta seja perdida.