как подать сигнал на событие tail -f

14

Я хочу, чтобы мой компьютер издавал звуковой сигнал при каждом хвостовом событии.

У меня есть следующая команда

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

Есть ли простой способ, как труба к тому, что пищит? нравиться

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

если да, то будет ли отображаться вывод grep?

Якоб Косороаба
источник
есть звуковая программа с репозиторием по умолчанию для Debian, и варианты просто apt-get install beep, но он не работает с трубопроводом таким образом
Jakob Cosoroaba

Ответы:

16

Просто определите beepследующее:

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

Затем вы можете использовать вашу команду:

tail -f development.log | grep "something rare" | beep
mouviciel
источник
1
извините, но это не работает, ничего не
издает
4
Хотя прямой вывод tail -f является немедленным, он буферизуется, как только проходит через канал. Вы должны ждать достаточно «чего-то редкого», прежде чем что-то наблюдать.
mouviciel
Вы можете передать результат через sedили аналогичным образом (между tail и grep), чтобы с помощью регулярного выражения заменить его на something rareсебя много раз. Сколько раз это нужно сделать, зависит от того, насколько труба буферизована.
Дэвид Спиллетт
6
@ Дэвид - Это хитовый подход. Если вы хотите отменить буфер данных, передаваемых по каналу, используйте любой из методов, описанных в этих ответах: stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe
2
Если исходить из предложения @ nagul, вот вызов, который работал для меня:tail -f development.log | stdbuf -oL -eL grep "something rare" | beep
GuitarPicker
10

Экран GNU имеет встроенную функцию звукового сигнала при изменении данного окна: см. Соответствующий раздел справочной страницы .

Заголовок резюме:

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

Как отмечалось в комментариях, это будет звучать при каждой новой записи в журнале, а не только над теми, которые соответствуют «чему-то редкому», так что это не совсем то, о чем просил ОП. Еще полезный трюк знать ИМХО.

Вы можете получить лучшее из обоих миров, открыв два screenокна ( <C-a> cчтобы открыть окно, <C-a> <C-a>переключаться между двумя окнами):

  1. контролируется, с tail -f yourfile.log | grep 'something rare'
  2. без контроля, с равниной tail -f yourfile.log

Затем вы можете наблюдать за прокруткой журнала в окне 2, и вы услышите сигнал из окна 1, когда произойдет «что-то редкое».

screen удивительно универсален - я настоятельно рекомендую прочитать об этом.

Сэм Стоукс
источник
1
Это не будет звучать только на «что-то редкое», не так ли?
1
Это было бы , если все , что происходило в этом конкретном окна , tail -f yourfile.log | grep something\ rareа не простоtail -f logfile
Дэвид Spillett
Ой, я не заметил, что он хотел только звуковой сигнал something rare. Отредактировано, чтобы отразить это. Grep сработал бы, но тогда он не увидел бы остальную часть журнала, только редкие строки - насколько я понимаю, он хочет иметь возможность просматривать весь журнал, прокручивающийся мимо, но быть предупрежденным о конкретных событиях.
Сэм Стоукс
1

Вы можете остановить буферизацию вывода в команде grep. Смотрите man grep для деталей.

Вы можете направить вывод grep в звуковой сигнал.

Следующий пример от man beep ...

   As part of a log-watching pipeline

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

В этих руководствах много хорошего. Если бы нам не нужно было читать их, чтобы найти это. ;-)

Читатель
источник
1

Команда watch имеет опцию --beep, и вы также можете установить интервал опроса, но стандарт с 2 секундами должен быть в порядке

watch --beep 'tail development.log | grep "something rare"'
oanoss
источник
1
Обратите внимание, что watchработает, выполняя ваш параметр / команду каждый (интервал) разделов, а затем результаты до предыдущего запуска. Таким образом , вы будете хотеть использовать обычную версию команды хвост, вместо использованияtail -f
RyanWilcox
Это не сработало для меня (несмотря на добавление watch --beepи завертывание моего хвоста / grep, я все еще не получил звуковой сигнал).
machineghost
1

Вы можете использовать sed для добавления control-G следующим образом:

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

или просто в редких строках, без использования grep, следующим образом:

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

в котором говорится: на линиях , где происходит что - то редкое, S ubstitute все для того же материала с контролем-G прикрепил на конце, и печати (но не печатать несовпадающих строк). Прекрасно работает!

Mi5ke
источник
0

Хм, сложно. Мы могли бы сделать что-то подобное?

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

Или в вашем случае

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

Кажется, что он делает некоторую буферизацию, хотя. Я посмотрю, есть ли способ отключить эту буферизацию с помощью forцикла.

Очевидно, вы должны иметь возможность регулировать буферизацию канала с помощью, ulimit -pно это продолжает жаловаться на неверный аргумент для меня. Я также нашел пост, в котором утверждается, что вам нужно перекомпилировать ядро, чтобы изменить это ограничение.

Иван Вучица
источник
0

В предыдущей работе я не мог получить надежного наблюдателя только с помощью команды fu, поэтому у меня был скрипт-обертка, подобный приведенному ниже, который проверял файл каждые секунды poll_duration и выискивал новые строки для интересующей фразы.

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

Это было на Unix-машине. В Linux вы можете сделать это лучше, используя интерфейс inotify filewatcher. Если этот пакет ( inotify-tools в Ubuntu) присутствует, замените

sleep $poll_duration 

с

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

Этот вызов блокируется, пока файл не будет изменен. Блокирующая версия почти так же эффективна, как и та, которую вы получите с tail -fверсией, если канал можно настроить для работы без буферизации.

Примечание . Сценарий сначала выполняет процедуру, head --lines=$new_linecountчтобы гарантировать, что строки, добавленные в файл после того, как мы его проверили, не перекосят кусок файла, который проверяется в этом цикле.


источник