come emettere un segnale acustico sull'evento tail -f


14

Voglio che il mio PC emetta un segnale acustico di sistema su ogni evento di coda

Ho il seguente comando

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

c'è un modo semplice come collegarlo a qualcosa che emette un segnale acustico? piace

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

in tal caso verrà comunque mostrato l'output grep?


c'è un programma beep con è nel repository predefinito per debian e le varianti solo apt-get install beep ma non funziona con il piping in questo modo
Jakob Cosoroaba

Risposte:


16

Basta definire beepcome segue:

beep() { read a || exit; printf "$a\007\n"; beep; }

Quindi, puoi usare il tuo comando:

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

1
scusate ma non funziona, non
emette

4
Sebbene l'output diretto di tail -f sia immediato, viene bufferizzato non appena passa attraverso una pipe. Devi aspettare abbastanza "qualcosa di raro" prima di osservare qualcosa.
mouviciel,

Potresti passare l'output attraverso sedo simili (tra tail e grep) a con un regexp sostituirlo something rarecon se stesso molte volte. Quante volte deve essere fatto dipende da quanto viene bufferizzato il tubo.
David Spillett,

6
@ David - Questo è un approccio incostante. Se si desidera unbuffer i dati passati attraverso un tubo, utilizzare uno dei metodi descritti in queste risposte: stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe

2
Andando fuori dal suggerimento di @ nagul, ecco l'invocazione che ha funzionato per me:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker

10

Lo schermo GNU ha una funzione integrata per emettere un segnale acustico quando cambia una determinata finestra: vedere la sezione relativa della pagina man .

Riepilogo del titolo:

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

Come sottolineato nei commenti, questo emetterà un segnale acustico su ogni nuova voce di registro, non solo su quelle che corrispondono a "qualcosa di raro", quindi questo non fa esattamente ciò che l'OP ha richiesto. Ancora un trucco utile per conoscere IMHO.

Puoi ottenere il meglio da entrambi i mondi aprendo due screenfinestre ( <C-a> cper aprire una finestra, <C-a> <C-a>per passare da una finestra all'altra):

  1. monitorato, con tail -f yourfile.log | grep 'something rare'
  2. non monitorato, con una pianura tail -f yourfile.log

Quindi puoi sederti guardando il registro scorrere oltre nella finestra 2 e verrai emesso un segnale acustico dalla finestra 1 quando si verifica "qualcosa di raro".

screen è straordinariamente versatile - consiglio vivamente di leggerlo.


1
Non suonerebbe solo su "qualcosa di raro", vero?

1
Sarebbe se tutto ciò che stava accadendo in quella particolare finestra tail -f yourfile.log | grep something\ rarenon fosse solo iltail -f logfile
David Spillett,

Oops, non ho notato che voleva solo un segnale acustico something rare. Modificato per riflettere questo. Il grep avrebbe funzionato, ma poi non avrebbe visto il resto del registro, solo le righe rare - a quanto ho capito, vuole essere in grado di guardare l'intero registro che scorre oltre, ma essere avvisato su eventi specifici.
Sam Stokes,

1

È possibile interrompere l'output del buffer nel comando grep. Vedi man grep per i dettagli.

È possibile reindirizzare l'output di grep in un segnale acustico.

Il seguente esempio è di beep uomo ...

   As part of a log-watching pipeline

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

Ci sono molte cose buone in quei manuali. Se solo non dovessimo leggerli per trovarlo. ;-)


1

Il comando watch ha un'opzione --beep e puoi anche impostare l'intervallo di polling, ma lo standard con 2 secondi dovrebbe essere ok

watch --beep 'tail development.log | grep "something rare"'

1
Nota, watchfunziona eseguendo il parametro / comando ogni sezione (intervallo) quindi arrivando i risultati alla corsa precedente. Quindi ti consigliamo di utilizzare la versione normale del comando tail, invece di usaretail -f
RyanWilcox il

Questo non ha funzionato per me (nonostante abbia aggiunto watch --beepe avvolto la coda / grep, non ho ancora ricevuto un segnale acustico).
machineghost

1

Puoi usare sed per aggiungere control-G come segue:

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

o solo su linee rare, senza usare grep, come segue:

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

che dice: sulle linee in cui si verifica qualcosa di raro, s tutto ubstitute per la stessa roba con il controllo-G appiccicato alla fine, e la stampa (ma non stampare le righe non corrispondenti). Funziona alla grande!


0

Hm, difficile. Potremmo forse fare qualcosa del genere?

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

O nel tuo caso

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

Sembra che stia facendo un po 'di buffering. Vedrò se c'è un modo per disattivare questo buffering dal forloop.

Apparentemente, dovresti essere in grado di regolare il buffering di pipe usando ulimit -pma ciò continua a lamentarmi di argomenti non validi. Ho anche trovato un post che afferma che è necessario ricompilare il kernel per modificare questo limite.


0

In un precedente lavoro, non ero in grado di ottenere un watcher affidabile con solo command-fu, quindi avevo uno script wrapper come quello qui sotto, che controllava il file ogni poll_duration secondi e inseriva le nuove righe per la frase interessata.

#!/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

Questo era su una macchina Unix. Su Linux, puoi fare di meglio usando la sua interfaccia inotify filewatcher. Se questo pacchetto ( inotify-tools su Ubuntu) è presente, sostituirlo

sleep $poll_duration 

con

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

Questa chiamata si blocca fino a quando il file non viene modificato. La versione bloccante è quasi altrettanto efficace di quella che otterresti con la tail -fversione se pipe potesse essere configurato per funzionare senza buffering.

Nota: per prima cosa lo script head --lines=$new_linecountgarantisce che le righe aggiunte al file dopo averlo verificato non inclinino il blocco del file che viene controllato in questo loop.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.