wie man auf Schwanz piept

14

Ich möchte, dass mein PC bei jedem Endereignis einen Signalton abgibt

Ich habe den folgenden Befehl

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

Gibt es eine einfache Möglichkeit, es an etwas zu leiten, das piept? mögen

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

Wenn ja, wird die Grep-Ausgabe weiterhin angezeigt?

Jakob Cosoroaba
quelle
Es gibt ein Piepton-Programm, das im Standardrepo für Debian enthalten ist, und Varianten, die nur den Piepton "apt-get install" enthalten, aber es funktioniert nicht mit dem Piping auf diese Weise
Jakob Cosoroaba

Antworten:

16

Definieren Sie einfach beepwie folgt:

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

Dann können Sie Ihren Befehl verwenden:

tail -f development.log | grep "something rare" | beep
mouviciel
quelle
1
Entschuldigung, aber das funktioniert nicht, es
piept
4
Obwohl die direkte Ausgabe von tail -f sofort erfolgt, wird sie gepuffert, sobald sie eine Pipe passiert. Sie müssen auf genug "etwas Seltenes" warten, bevor Sie etwas beobachten.
mouviciel
Sie könnten die Ausgabe durchlaufen lassen sedoder ähnlich (zwischen tail und grep), um die something raremit sich selbst oft durch eine reguläre Ausdrucksweise zu ersetzen . Wie oft es durchgeführt werden muss, hängt davon ab, wie viel die Pipe gepuffert ist.
David Spillett
6
@ David - Das ist ein Hit-and-Miss-Ansatz. Wenn Sie die über eine Pipe übertragenen Daten entpuffern
möchten
2
Ausgehend von @ naguls Vorschlag ist hier der Aufruf, der für mich funktioniert hat:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker
10

Der GNU-Bildschirm verfügt über eine integrierte Funktion, die einen Piepton ausgibt, wenn sich ein bestimmtes Fenster ändert: siehe den entsprechenden Abschnitt auf der Manpage .

Zusammenfassung der Überschrift:

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

Wie in den Kommentaren erwähnt, ertönt bei jedem neuen Protokolleintrag ein Piepton , nicht nur bei den Einträgen, die mit "etwas Seltenem" übereinstimmen. Dies entspricht also nicht den Anforderungen des OP. Immer noch ein nützlicher Trick, um IMHO zu kennen.

Sie können das Beste aus beiden Welten herausholen, indem Sie zwei screenFenster <C-a> cöffnen ( um ein Fenster zu öffnen, <C-a> <C-a>zwischen zwei Fenstern zu wechseln):

  1. überwacht, mit tail -f yourfile.log | grep 'something rare'
  2. unüberwacht, mit einer Ebene tail -f yourfile.log

Dann können Sie das Protokoll in Fenster 2 vorbeirollen sehen, und Sie werden von Fenster 1 aus einen Piepton erhalten, wenn "etwas Seltenes" auftritt.

screen ist unglaublich vielseitig - ich empfehle dringend, es nachzulesen.

Sam Stokes
quelle
1
Das würde doch nicht nur bei "etwas Seltenem" piepen, oder?
Nagul
1
Es wäre, wenn alles, was in diesem bestimmten Fenster geschah, tail -f yourfile.log | grep something\ rareeher als nur dastail -f logfile
David Spillett
Hoppla, ich habe nicht bemerkt, dass er nur einen Piepton wollte something rare. Bearbeitet, um dies widerzuspiegeln. Das grep würde funktionieren, aber dann würde er den Rest des Protokolls nicht sehen, nur die seltenen Zeilen - so wie ich es verstehe, möchte er in der Lage sein, das gesamte Protokoll vorbeirollen zu sehen, aber über bestimmte Ereignisse informiert zu werden.
Sam Stokes
1

Sie können verhindern, dass die Ausgabe im Befehl grep zwischengespeichert wird. Siehe man grep für Details.

Sie können die Grep-Ausgabe in einen Piepton umleiten.

Das folgende Beispiel stammt von einem Piepton ...

   As part of a log-watching pipeline

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

In diesen Handbüchern steckt eine Menge Gutes. Wenn wir sie nur nicht lesen müssten, um sie zu finden. ;-)

Ein Leser
quelle
1

Der watch-Befehl hat eine --beep-Option, und Sie können auch das Abfrageintervall einstellen, aber der Standard mit 2 Sekunden sollte in Ordnung sein

watch --beep 'tail development.log | grep "something rare"'
oanoss
quelle
1
Beachten Sie, dass Sie watchIhren Parameter / Befehl alle (Intervall-) Abschnitte ausführen und dann die Ergebnisse zum vorherigen Durchlauf zurückführen. Daher sollten Sie die normale Version des Befehls tail verwenden, anstatttail -f
RyanWilcox
Das hat bei mir nicht funktioniert (obwohl ich watch --beepmeinen Schwanz / Grep hinzugefügt und eingewickelt habe, bekam ich immer noch keinen Piepton).
Maschinengeist
1

Sie können sed verwenden, um das Steuerelement G wie folgt hinzuzufügen:

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

oder nur in seltenen Zeilen, ohne grep zu verwenden, wie folgt:

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

die sagt: auf den Linien , wo etwas selten auftritt, s ubstitute alles für den gleichen Stoff mit Steuer-G gehefteten am Ende, und druckt (aber nicht die nicht passenden Zeilen drucken). Funktioniert super!

Mi5ke
quelle
0

Hm, schwierig. Wir könnten vielleicht so etwas tun?

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

Oder in deinem Fall

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

Es scheint jedoch etwas zu puffern. Ich werde schauen, ob es eine Möglichkeit gibt, diese Pufferung durch die forSchleife auszuschalten .

Anscheinend sollten Sie in der Lage sein, die Pufferung der Pipe mit anzupassen, ulimit -paber das klagt mich immer wieder über ein ungültiges Argument an. Ich habe auch einen Beitrag gefunden, der behauptet, dass Sie den Kernel neu kompilieren müssen, um dieses Limit zu ändern.

Ivan Vučica
quelle
0

In einem früheren Job konnte ich mit nur command-fu keinen zuverlässigen Beobachter finden, daher hatte ich ein Wrapper-Skript wie das folgende, das alle poll_duration Sekunden die Datei inspizierte und die neuen Zeilen nach dem interessierten Ausdruck durchsuchte.

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

Dies war auf einer Unix-Maschine. Unter Linux können Sie mithilfe der inotify- Filewatcher-Oberfläche eine Verbesserung erzielen. Wenn dieses Paket ( inotify-tools unter Ubuntu) vorhanden ist, ersetzen Sie es

sleep $poll_duration 

mit

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

Dieser Aufruf wird blockiert, bis die Datei geändert wurde. Die blockierende Version ist fast so effizient wie die tail -fVersion, wenn die Pipe so konfiguriert werden könnte, dass sie ohne Pufferung funktioniert.

Hinweis: Das Skript führt zunächst eine head --lines=$new_linecountAktion aus, um sicherzustellen, dass Zeilen, die der Datei hinzugefügt wurden, nachdem wir sie überprüft haben, den Teil der Datei, der in dieser Schleife überprüft wird, nicht verzerren.

Nagul
quelle