Verifica se condicional com awk para correspondências no logfile

3

Eu quero verificar o arquivo auth.log para conexões sshd aceitas e executar uma ação se alguma for encontrada.

Aqui está o meu código:

tail -f /var/log/auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'

Por algum motivo, isso não produz saída. Alguém pode explicar por quê?

    
por Chris 09.06.2015 / 11:50

2 respostas

5

Eu acho que seu problema está relacionado ao buffer de tail -f :

~$ tail auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'
FOUND
FOUND

Funciona com tail , mas falha com tail -f :

~$ tail -f auth.log | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND") } }'
^C

Uma solução alternativa que você pode usar é usar um loop while para ler cada linha de tail -f :

~$ tail -f auth.log | while read line
> do
>     echo $line | awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { system("echo FOUND")} }'
> done
FOUND
FOUND

-

Pesquisando man awk para buffer , encontrei a opção -W (mas esta é uma versão mawk …):

-W interactive

    sets unbuffered writes to stdout and line buffered reads from stdin. Records from stdin are lines regardless of the value of RS.

também:

mawk accepts abbreviations for any of these options, e.g., “-W i” and “-Wi” …

~$ tail -f auth.log | awk  -Wi  '/sshd/ && /Accepted/ {system("echo FOUND")}'
FOUND
FOUND
    
por 09.06.2015 / 12:02
3

Você também pode usar a chamada fflush() do awk para liberar a saída:

tail -f /var/log/auth.log | 
    awk '{ if($0 ~ /sshd/ && $0 ~ /Accepted/) { fflush(); system("echo FOUND") } }'

Dito isto, o seu awk é desnecessariamente complexo. Tudo que você precisa é:

tail -f /var/log/auth.log | awk '/sshd/ && /Accepted/{ fflush(); print "FOUND"}'
    
por 09.06.2015 / 12:46