cómo emitir un pitido en el evento tail -f

14

Quiero que mi PC emita un pitido del sistema en cada evento de cola

Tengo el siguiente comando

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

¿Hay alguna manera fácil como canalizarlo a algo que suene? me gusta

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

si es así, ¿se mostrará la salida grep?

Jakob Cosoroaba
fuente
hay un programa de pitidos con el repositorio predeterminado para Debian y las variantes solo apt-get install bip, pero no funciona con la tubería de esta manera
Jakob Cosoroaba

Respuestas:

16

Simplemente defina beeplo siguiente:

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

Entonces, puedes usar tu comando:

tail -f development.log | grep "something rare" | beep
Mouviciel
fuente
1
lo siento, pero esto no funciona, no
emite
44
Aunque la salida directa de tail -f es inmediata, se amortigua tan pronto como atraviesa una tubería. Tienes que esperar suficiente "algo raro" antes de observar algo.
mouviciel
Puede pasar la salida a través de sedo similar (entre cola y grep) con una expresión regular reemplazar la something raremisma muchas veces. La cantidad de veces que debe hacerse depende de la cantidad de almacenamiento de la tubería.
David Spillett el
66
@David: ese es un enfoque impredecible. Si desea liberar los datos pasados ​​a través de una tubería, utilice cualquiera de los métodos descritos en estas respuestas: stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe
2
Saliendo de la sugerencia de @ nagul, aquí está la invocación que funcionó para mí:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker el
10

La pantalla GNU tiene una función incorporada para emitir un pitido cuando cambia una ventana determinada: consulte la sección correspondiente de la página de manual .

Resumen del titular:

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

Como se señaló en los comentarios, esto emitirá un pitido en cada entrada de registro nueva, no solo en aquellas que coincidan con "algo raro", por lo que esto no hace exactamente lo que solicitó el OP. Sigue siendo un truco útil para saber en mi humilde opinión.

Puede obtener lo mejor de ambos mundos abriendo dos screenventanas ( <C-a> cpara abrir una ventana, <C-a> <C-a>para alternar entre dos ventanas):

  1. monitoreado, con tail -f yourfile.log | grep 'something rare'
  2. sin vigilancia, con una llanura tail -f yourfile.log

Luego, puede sentarse mirando el registro desplazarse en la ventana 2, y se escuchará un pitido desde la ventana 1 cuando ocurra "algo raro".

screen es increíblemente versátil: recomiendo leerlo.

Sam Stokes
fuente
1
Eso no sonaría solo en "algo raro", ¿verdad?
1
Lo que sería si todo lo que sucedía en esa ventana en particular es tail -f yourfile.log | grep something\ raremás que sólo eltail -f logfile
David Spillett
Vaya, no me di cuenta de que solo quería un pitido something rare. Editado para reflejar esto. El grep funcionaría, pero luego no vería el resto del registro, solo las líneas raras; según tengo entendido, quiere poder ver todo el registro desplazándose, pero recibir alertas sobre eventos específicos.
Sam Stokes
1

Puede detener la salida de la memoria intermedia en el comando grep. Ver man grep para más detalles.

Puede canalizar la salida grep en pitido.

El siguiente ejemplo es del hombre beep ...

   As part of a log-watching pipeline

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

Hay muchas cosas buenas en esos manuales. Si tan solo no tuviéramos que leerlos para encontrarlo. ;-)

Un lector
fuente
1

El comando watch tiene una opción --beep, y también puede establecer el intervalo de sondeo, pero el estándar con 2 segundos debería estar bien

watch --beep 'tail development.log | grep "something rare"'
oanoss
fuente
1
Tenga en cuenta que watchfunciona ejecutando su parámetro / comando en cada sección (intervalo) y luego enviando los resultados a la ejecución anterior. Por lo tanto, querrá usar la versión normal del comando de cola, en lugar de usartail -f
RyanWilcox
Esto no funcionó para mí (a pesar de agregar watch --beepy envolver mi cola / grep, aún no recibí un pitido).
machineghost el
1

Puede usar sed para agregar el control-G de la siguiente manera:

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

o solo en líneas raras, sin usar grep, de la siguiente manera:

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

que dice: en las líneas donde se produce algo raro, s ubstitute todo por el mismo material con el control G-tachuelas en el final, y de impresión (pero no se imprimen las líneas no coincidentes). ¡Funciona genial!

Mi5ke
fuente
0

Hm, complicado. ¿Quizás podríamos hacer algo como esto?

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

O en tu caso

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

Sin embargo, parece estar haciendo algo de almacenamiento en búfer. Veré si hay una manera de desactivar este almacenamiento intermedio por forbucle.

Aparentemente, deberías poder ajustar el almacenamiento en búfer de la tubería mediante el uso, ulimit -ppero eso sigue quejándome sobre el argumento no válido para mí. También encontré una publicación que dice que necesitas recompilar el kernel para cambiar este límite.

Ivan Vučica
fuente
0

En un trabajo anterior, no pude conseguir un observador fiable con solo comando-fu, así que tenía un guión envoltorio como la de abajo, que inspeccionó el archivo cada poll_duration segundos y grepped las nuevas líneas para la frase interesados.

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

Esto estaba en una máquina Unix. En Linux, puede ir mejor usando su interfaz inotify filewatcher. Si este paquete ( inotify-tools en Ubuntu) está presente, reemplace

sleep $poll_duration 

con

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

Esta llamada se bloquea hasta que se modifica el archivo. La versión de bloqueo es casi tan eficiente como lo que obtendría con la tail -fversión si la tubería se pudiera configurar para funcionar sin almacenamiento en búfer.

Nota: El script primero hace una head --lines=$new_linecountpara garantizar que las líneas agregadas al archivo después de que lo verifiquemos no sesguen el fragmento del archivo que se verifica en este bucle.


fuente