como bipar na cauda -f event

13

Eu quero que meu PC faça um bipe do sistema em todos os eventos finais

Eu tenho o seguinte comando

tail -f development.log | grep "something rare"

Existe uma maneira fácil como canalizar para algo que apita? como

tail -f development.log | grep "something rare" | beep

se for assim, a saída do grep ainda será mostrada?

    
por Jakob Cosoroaba 07.09.2009 / 14:55

7 respostas

14

Basta definir beep da seguinte forma:

beep() { read a || exit; printf "$a
tail -f development.log | grep "something rare" | beep
7\n"; beep; }

Depois, você pode usar o seu comando:

beep() { read a || exit; printf "$a
tail -f development.log | grep "something rare" | beep
7\n"; beep; }
    
por 07.09.2009 / 15:19
9

A tela GNU tem um recurso embutido para bipar quando uma determinada janela muda: veja a seção relevante da página do manual .

Resumo do título:

$ screen
$ tail -f yourfile.log    # inside the screen session
<C-a> M    # "Window 0 (bash) is now being monitored for all activity."

Como apontado nos comentários, isso vai bipar em todas as novas entradas de log, não apenas aquelas que correspondem a "algo raro", então isso não faz o que o OP pediu. Ainda um truque útil para saber IMHO.

Você pode obter o melhor dos dois mundos abrindo duas screen windows ( <C-a> c para abrir uma janela, <C-a> <C-a> para alternar entre duas janelas):

  1. monitorado, com tail -f yourfile.log | grep 'something rare'
  2. não monitorado, com um tail -f yourfile.log simples

Então você pode se sentar assistindo a rolagem do log passado na janela 2, e você será bipado da janela 1 quando ocorrer "algo raro".

screen é incrivelmente versátil - recomendo muito ler isso.

    
por 07.09.2009 / 16:43
1

Você pode impedir que a saída seja armazenada em buffer no comando grep. Veja man grep para detalhes.

Você pode enviar a saída do grep para o bipe.

O exemplo a seguir é do beep do homem ...

   As part of a log-watching pipeline

          tail -f /var/log/xferlog | grep --line-buffered passwd | \
          beep -f 1000 -r 5 -s

Há muitas coisas boas nesses manuais. Se ao menos não precisássemos lê-los para encontrá-lo. ; -)

    
por 20.04.2011 / 12:14
1

O comando watch tem uma opção --beep, e você pode definir o intervalo de polling também, mas o padrão com 2 seg deve estar ok

watch --beep 'tail development.log | grep "something rare"'
    
por 28.03.2012 / 12:13
1

Você poderia usar sed para adicionar o controle-G da seguinte forma:

tail -f myFile | sed "s/.*/&\x07/"

ou apenas em linhas raras, sem usar o grep, como segue:

tail -f myFile | sed -n "/something rare/s/.*/&\x07/p"

que diz: nas linhas em que algo raro ocorre, s ubstitute tudo para o mesmo material com controle-G no final e imprima (mas não imprima as linhas não correspondentes ). Funciona muito bem!

    
por 17.10.2015 / 13:54
0

Hm, complicado. Nós poderíamos talvez fazer algo assim?

for i in 'find | grep 7171'; do beep; echo $i; done

Ou no seu caso

for i in 'tail -f development.log | grep "something rare"'; do beep; echo $i; done

Parece estar fazendo algum buffer embora. Vou procurar se há uma maneira de desativar esse buffer pelo loop for .

Aparentemente, você deve ser capaz de ajustar o buffer do pipe usando ulimit -p , mas isso continua reclamando sobre argumentos inválidos para mim. Eu também encontrei um post que afirma que você precisa recompilar o kernel para alterar este limite.

    
por 07.09.2009 / 15:13
0

Em um trabalho anterior, eu não conseguia um observador confiável com apenas comando-fu, então eu tinha um script de wrapper como o abaixo, que inspecionava o arquivo a cada poll_duration segundos e continha o novas linhas para a frase interessada.

#!/bin/bash

file=$1
phrase=$2
poll_duration=$3

typeset -i checked_linecount
typeset -i new_linecount
typeset -i new_lines
let checked_linecount=new_linecount=new_lines=0
echo "Watching file $file for phrase \"$phrase\" every $poll_duration seconds"

while [ 1 ]
do
        let new_linecount='wc -l $file| awk '{print $1}''
        if [[ $new_linecount > $checked_linecount ]]; then
                let "new_lines = $new_linecount-$checked_linecount"
                head --lines=$new_linecount "$file" | tail --lines=$new_lines | grep "$phrase" && beep
                let checked_linecount=$new_linecount
        fi
        sleep $poll_duration
done

Isso foi em uma máquina Unix. No Linux, você pode ir melhor usando a interface do inotify filewatcher. Se este pacote ( inotify-tools no Ubuntu) estiver presente, substitua

sleep $poll_duration 

com

inotifywait -e modify "$file"  1>/dev/null 2>&1

Esta chamada bloqueia até o arquivo ser modificado. A versão de bloqueio é quase tão eficiente quanto o que você teria com a versão tail -f se o pipe pudesse ser configurado para funcionar sem buffer.

Nota: O script primeiro faz um head --lines=$new_linecount para garantir que as linhas adicionadas ao arquivo após a verificação não distorçam o pedaço do arquivo que é verificado nesse loop.

    
por 07.09.2009 / 21:30