Redirecionamento aninhado em BASH

2

Eu tenho um cenário onde eu quero filtrar arquivos de log. Para fazer isso eu estou querendo seguir as últimas 10 linhas ou mais de um arquivo de log e como novas linhas são lidas, canalizá-las através de um programa awk e redirecionar a saída para uma porta de escuta em um host remoto via netcat.

Atualmente meu script tem a seguinte linha:

echo "\`awk -f rules.awk <(tail -F $@)\`" | nc -u 127.0.0.1 5004

Onde $@ é a lista de argumentos fornecida na chamada inicial e o rules.awk simplesmente contém alguns padrões desejados para combinar.

Chamando o script com ./script logfile.log parece não fazer nada e o script trava. Eu especulo que o pipe realmente requer que um processo termine antes que sua saída final seja canalizada para o novo comando.

Então eu tentei uma abordagem diferente executando o seguinte no meu terminal:

nc -u 127.0.0.1 5004 <(awk -f rules.awk <(tail -F logfile.log))

Isso resultou no seguinte erro:

Invalid port specification: /dev/fd/63

Parece que o redirecionamento realmente passou o dispositivo lógico do fluxo em vez de seu "valor", mas estou apenas adivinhando novamente.

Poderia alguém com um pouco mais de BASH me apontar na direção certa com isso?

Troy Patrick
fonte
Eu acho que não estou claro sobre o que você quer fazer. Desde que você está fazendo uma cauda -f, nunca terminará. Ele deve passar a saída para nc regularmente (provavelmente seguindo blocos de 1k ou 4k, dependendo do tipo de buffer que awk e nc estão fazendo. Quando você deseja que esse comando termine?
Alan Shutko
Não precisaria. Ele poderia continuar rodando em um shell e enviar as linhas relevantes nos arquivos de log para um servidor para indexação em tempo real. Não precisa fazer isso, mas eu pensei que seria um bom ter, então estou ansioso para fazê-lo funcionar. O que você diz sobre o buffer é interessante. Meu arquivo de teste é muito pequeno, então vou tentar com um arquivo maior (& gt; 4K)
Troy Patrick
Mais informações sobre o que estou fazendo: a empresa para a qual trabalho é querer usar um produto chamado Splunk para indexar arquivos de log e expor a inteligência comercial que eles contêm. O licenciamento do Splunk é baseado na quantidade de dados indexados por dia, e é por isso que estou escrevendo este script para reduzir os dados enviados ao servidor do Splunk para indexação.
Troy Patrick

Respostas:

1

Os descritores de arquivos são um pouco confusos, eles são certamente mais confusos do que os pipes. Então, antes de tentar redirecionar a saída de um subshell ( & lt; () ) como entrada padrão para um comando, tente obter o que você deseja com pipes. Além disso, pode ajudar a obter os comandos de saída funcionando corretamente antes de enviar a entrada para um comando de destino (nc).

cat <(tail -F /var/log/daemon.log ) | cat -n | awk 'NR>3 { print}'

isso é equivalente a

tail -F /var/log/daemon.log | cat -n | awk 'NR>3 {print}';

mas "melhor", uma vez que não se baseia na sintaxe específica do bash `& lt; () '

Ярослав Рахматуллин
fonte
0

De improviso, isso parece que deveria funcionar para mim

tail -F $@ | awk -f rules.awk | nc -u 127.0.0.1 5004
Alan Shutko
fonte
Eu também pensava assim, mas olhando para isso eu acho que não: smop.co.uk/blog/index.php/2006/06/26/tail-f-and-awk É o sinalizador seguinte que está causando os problemas. Se eu removê-lo, o que você sugeriu funcionará.
Troy Patrick
Isso funciona. Parecia que não era, mas acho que foi realmente um problema com o armazenamento em buffer. Se eu tentei isso com um arquivo de entrada significativamente grande, obtive o comportamento que queria.
Troy Patrick