jak emitować sygnał dźwiękowy podczas zdarzenia tail -f

14

Chcę, aby mój komputer generował dźwięk systemowy przy każdym zdarzeniu ogona

Mam następujące polecenie

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

czy jest prosty sposób na podłączenie go do czegoś, co emituje sygnał dźwiękowy? lubić

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

jeśli tak, to czy wyjście grep nadal będzie wyświetlane?

Jakob Cosoroaba
źródło
istnieje program dźwiękowy z domyślnym repozytorium dla debiana, a warianty po prostu apt-get install beep, ale nie działa w ten sposób z
potokowaniem

Odpowiedzi:

16

Po prostu zdefiniuj beepnastępująco:

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

Następnie możesz użyć polecenia:

tail -f development.log | grep "something rare" | beep
mouviciel
źródło
1
przepraszam, ale to nie działa, nic nie wydaje sygnału ani nie drukuje
Jakob Cosoroaba,
4
Chociaż bezpośrednie wyjście tail -f jest natychmiastowe, jest buforowane, gdy tylko przejdzie przez potok. Zanim zaczniesz coś obserwować, musisz poczekać na wystarczającą „coś rzadkiego”.
mouviciel
Możesz przekazać wyjście przez sedlub podobnie (między ogonem i grepem), używając wyrażenia regularnego zamieniając je na something raresiebie wiele razy. Ile razy trzeba to zrobić, zależy od tego, ile rury jest buforowane.
David Spillett,
6
@David - To podejście typu hit-miss. Jeśli chcesz
2
Wychodząc od sugestii @ nagul, oto inwokacja, która zadziałała dla mnie:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker
10

Ekran GNU ma wbudowaną funkcję sygnalizowania dźwiękiem, gdy dane okno się zmienia: patrz odpowiedni rozdział strony podręcznika .

Podsumowanie nagłówka:

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

Jak wskazano w komentarzach, będzie to wydawać sygnał dźwiękowy przy każdym nowym wpisie dziennika, nie tylko tym, które pasują do „czegoś rzadkiego”, więc nie robi to dokładnie tego, o co prosi OP. Nadal przydatna sztuczka, aby poznać IMHO.

Możesz uzyskać to, co najlepsze z obu światów, otwierając dwa screenokna ( <C-a> caby otworzyć okno i <C-a> <C-a>przełączać się między dwoma oknami):

  1. monitorowane, z tail -f yourfile.log | grep 'something rare'
  2. bez nadzoru, z równiną tail -f yourfile.log

Następnie możesz usiąść i obserwować, jak dziennik przewija się obok w oknie 2, a usłyszysz sygnał dźwiękowy z okna 1, gdy wystąpi „coś rzadkiego”.

screen jest niesamowicie wszechstronny - gorąco polecam lekturę.

Sam Stokes
źródło
1
Czy nie brzmiałby to tylko na „czymś rzadkim”?
1
Byłoby, gdyby wszystko, co działo się w tym konkretnym oknie, było tail -f yourfile.log | grep something\ rareczymś więcej niżtail -f logfile
David Spillett,
Ups, nie zauważyłem, że chce tylko dźwięk something rare. Edytowane, aby to odzwierciedlić. Grep zadziałałby, ale wtedy nie zobaczyłby reszty dziennika, tylko rzadkich linii - jak rozumiem, chce móc obserwować cały przewijany dziennik, ale być powiadamianym o określonych zdarzeniach.
Sam Stokes,
1

Możesz zatrzymać buforowanie danych wyjściowych za pomocą polecenia grep. Zobacz man grep po szczegóły.

Możesz przesłać wyjście grep do sygnału dźwiękowego.

Poniższy przykład pochodzi z sygnału dźwiękowego człowieka ...

   As part of a log-watching pipeline

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

W tych instrukcjach jest wiele dobrych rzeczy. Gdybyśmy nie musieli ich czytać, aby je znaleźć. ;-)

Czytelnik
źródło
1

Polecenie watch ma opcję --beep i możesz również ustawić interwał odpytywania, ale standardowy z 2 sekundami powinien być ok

watch --beep 'tail development.log | grep "something rare"'
oanoss
źródło
1
Uwaga: watchdziała, uruchamiając parametr / polecenie co sekcje (przedział), a następnie przechodząc wyniki do poprzedniego uruchomienia. Dlatego będziesz chciał użyć normalnej wersji polecenia tail zamiast zamiasttail -f
RyanWilcox
Nie działało to dla mnie (pomimo dodania watch --beepi zawinięcia ogona / grepa nadal nie dostałem sygnału).
machineghost
1

Możesz użyć sed, aby dodać control-G w następujący sposób:

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

lub tylko na rzadkich liniach, bez użycia grep, w następujący sposób:

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

który mówi: na liniach gdzie występuje czymś rzadkim, s ubstitute wszystko dla tej samej rzeczy z kontroli-G dołączona na końcu i drukuj (ale nie drukować linie niedopasowane). Działa świetnie!

Mi5ke
źródło
0

Hm, trudne. Może moglibyśmy zrobić coś takiego?

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

Lub w twoim przypadku

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

Wygląda na to, że trochę buforuje. Sprawdzę, czy istnieje sposób na wyłączenie tego buforowania za pomocą forpętli.

Najwyraźniej powinieneś być w stanie dostosować buforowanie potoku za pomocą, ulimit -pale to wciąż narzeka na mnie nieprawidłowy argument. Znalazłem również post, który mówi, że musisz zmienić kompilację jądra, aby zmienić ten limit.

Ivan Vučica
źródło
0

W poprzednim zadaniu nie mogłem uzyskać niezawodnego obserwatora z samym Command-fu, więc miałem skrypt otoki taki jak ten poniżej, który sprawdzał plik co sekundę poll_duration i przeszukiwał nowe wiersze dla zainteresowanej frazy.

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

To było na maszynie uniksowej. W systemie Linux możesz przejść o jeden lepszy, używając interfejsu inotify filtru plików. Jeśli ten pakiet ( inotify-tools w Ubuntu) jest obecny, zamień

sleep $poll_duration 

z

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

To wywołanie blokuje się, dopóki plik nie zostanie zmodyfikowany. Wersja blokująca jest prawie tak samo wydajna jak tail -fwersja, gdyby potok mógł zostać skonfigurowany do pracy bez buforowania.

Uwaga: Skrypt najpierw head --lines=$new_linecountsprawdza, czy wiersze dodane do pliku po sprawdzeniu go nie przekrzywiają fragmentu pliku, który jest sprawdzany w tej pętli.


źródło