'tail -f' até o texto ser visto

19

Eu tenho um servidor de IC com uma interface de linha de comando que me permite iniciar um trabalho remotamente ( jenkins servidor de IC e a ferramenta jenkins-cli.jar ).

Depois de largar o trabalho, eu tail -f the log (desculpe pelo comando bagunçado):

ssh -t my-jenkins-host.com "tail -f \"/var/lib/jenkins/jobs/$job_name/builds/\'ls -ltr /var/lib/jenkins/jobs/$job_name/builds/ | grep '^l' | tail -n 1|awk '{print \}'\'/log\""

Após a conclusão bem-sucedida do trabalho, geralmente após pelo menos 5 minutos, recebo a seguinte linha na saída:

Finished: SUCCESS

Existe uma boa maneira de parar de seguir o log neste momento? ou seja, existe como um comando tail_until 'some line' my-file.log ?

BÔNUS: crédito extra se você puder fornecer uma resposta que retorne 0 quando SUCCESS for correspondido, 1 quando FAILURE for correspondido e sua solução funcionar no mac! (que eu acredito ser baseado em bsd)

    
por aaronstacy 20.08.2012 / 22:56

7 respostas

38

Você pode enviar o tail -f para sed , pedindo para sair quando vir a linha que você está procurando:

tail -f /path/to/file.log | sed '/^Finished: SUCCESS$/ q'

sed produzirá cada linha processada por padrão e sairá depois de ver a linha. O processo tail será interrompido quando tentar gravar a próxima linha e perceber que seu canal de saída está quebrado

    
por 20.08.2012 / 23:10
6
tail -f my-file.log | grep -qx "Finished: SUCCESS"

-q , que significa quieto, sai assim que encontra uma correspondência

-x torna grep igual à linha inteira

Para a segunda parte, tente

tail -f my-file.log | grep -m 1 "^Finished: " | grep -q "SUCCESS$"

-m <number> diz ao grep para parar após número corresponder

e o status de saída grep -q será apenas 0 se SUCCESS for encontrado no final da linha

Se você quiser ver toda a saída, não pode usar grep -q , mas ainda pode fazer

tail -f my-file.log | grep -m 1 "^Finished: "

que faz tudo, exceto definir o status de saída para 1 se FAILURE aparecer.

    
por 20.08.2012 / 23:48
4

Uma variação da resposta de @ Mikel com os comentários de @Mrozek (eu teria respondido no comentário, mas acho que ainda não tenho privilégios suficientes)

tail -f my-file.log | tee >( grep -qx "Finished: SUCCESS" )

permitiria que você usasse a solução do @ Mikel e ainda veria a saída na tela

    
por 26.09.2012 / 23:43
2

Eu não gostei de nenhuma das respostas aqui, então decidi fazer as minhas. Este script bash atende a todos os critérios e inclui o BONUS para a saída de 1 na falha.

#!/bin/bash
while IFS= read -r LOGLINE || [[ -n "$LOGLINE" ]]; do
    printf '%s\n' "$LOGLINE"
    [[ "${LOGLINE}" == "Finished: SUCCESS" ]] && exit 0
    [[ "${LOGLINE}" == "Finished: FAILURE" ]] && exit 1
done < <(timeout 300 tail -f my-file.log)
exit 3

Também está incluído um recurso de tempo limite, que resultará em um código de saída 3. Se você não tiver o comando timeout no seu sistema, pegue o script timeout.sh de Anthony Thyssen:

link

Pelos comentários abaixo, atualizei a impressão de log para interromper a expansão do caractere de escape e incluí todos os recursos de uma 'leitura' padrão. Consulte o link para obter detalhes completos de 'leitura'. O cheque EOF não é necessário aqui, mas está incluído para ser completo.

    
por 21.09.2018 / 22:19
0

aqui está um script python que quase faz o que eu quero (veja abaixo):

import sys,re

def main():
    re_end = re.compile(sys.argv[1])
    re_fail = re.compile(sys.argv[2]) if len(sys.argv) > 2 else None
    for line in sys.stdin:
        sys.stdout.write(line)
        if re_end.match(line):
            sys.exit(0)
        elif re_fail and re_fail.match(line):
            sys.exit(1)

if __name__ == '__main__': main()

ressalvas:

  • as linhas não são impressas quando aparecem ... elas são impressas em grupos ... parece ser algum buffer acontecendo

  • Eu teria que instalar isso como um script no meu caminho ou algo assim, por isso é inconveniente, e eu prefiro um slick one-liner:)

por 20.08.2012 / 23:09
0

Eu tive problemas com sed e grep e suas opções, então eu escrevo o meu one with bash conditions

tail -f screenlog.* | 
while IFS= read line; 
 do 
   echo $line; 
   if [[ $line == *Started\ Application* ]]; 
    then pkill tail; 
   fi; 
done
    
por 27.04.2017 / 13:36
-1

Você também tenta

 grep -q 'App Started' <(tail -f /var/log/app/app.log)
    
por 20.02.2018 / 06:32

Tags