“tail -f | grep error ”com loop while não está funcionando

3

O comando abaixo não está dando nenhum resultado. Eu quero grep a linha de erro do arquivo e insira na tabela.

Comando que não está funcionando:

tail -f logfile.log | grep  ERROR|while read msg; do psql -d testdb -c insert into t values('$msg'); done

Mas se eu remover o código grep ERROR do comando, ele está funcionando como esperado. Não tenho certeza do que está acontecendo?

Comando que está funcionando bem:

tail -f logfile.log|while read msg; do psql -d testdb -c insert into t values('$msg'); done

Você pode assumir os dados abaixo no arquivo:

ERROR
sql committed
ERROR
ERROR
error
...
    
por ram 25.01.2018 / 09:44

1 resposta

6

Duas coisas:

  1. O código, como está escrito na pergunta, inserirá a string literal $msg (se funcionar), já que você usa aspas simples ao redor dela. Use aspas duplas em vez disso. Aqui, coloquei a instrução inteira entre aspas duplas, o que expandirá o $msg dentro. O código shell ainda é frágil, dependendo do que vem do grep . A sequência de caracteres em $msg deve idealmente ser adequadamente higienizada para que um único ' , ou outros caracteres especiais, não quebre a declaração (ou pior, veja comentário do usuário cas abaixo ).

    tail -f logfile.log |
    grep -F 'ERROR' |
    while read msg; do
        psql -d testdb -c "insert into t values('$msg')"
    done
    

    Também adicionei -F à invocação de grep enquanto pesquisamos com uma string fixa (isso é principalmente para fins de documentação).

  2. grep armazena em buffer sua saída, portanto, não produzirá nada até que seu buffer de saída esteja cheio. Isso dá a impressão de que "não está funcionando" quando, de fato, ocorre, mas não fará nada até que grep tenha liberado seu buffer de saída, o que acontece quando há dados suficientes nele. Esta é uma otimização de desempenho.

    O

    GNU grep (bem como algumas outras implementações do mesmo utilitário, por exemplo, o OpenBSD) pode ser feito com buffer de linha com sua opção --line-buffered :

    tail -f logfile.log |
    grep --line-buffered -F 'ERROR' |
    while read msg; do
        psql -d testdb -c "insert into t values('$msg')"
    done
    

Nota: Eu não testei isso porque atualmente não tenho uma instância do PostgreSQL (?) em execução.

    
por 25.01.2018 / 10:02