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

7880
Jakob Cosoroaba

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

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

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

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

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

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

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

7 ответов на вопрос

14
mouviciel

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

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

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

tail -f development.log | grep "something rare" | beep 
извините, но это не работает, ничего не издает звуковых сигналов и не печатает Jakob Cosoroaba 15 лет назад 0
Хотя прямой вывод tail -f является немедленным, он буферизуется, как только проходит через канал. Вы должны ждать достаточно «чего-то редкого», прежде чем что-то наблюдать. mouviciel 15 лет назад 3
Вы могли бы передать результат через `sed` или аналогичный (между tail и grep), чтобы с помощью регулярного выражения заменить` нечто редкое 'на себя много раз. Сколько раз это нужно сделать, зависит от того, насколько труба буферизована. David Spillett 15 лет назад 0
@ Дэвид - Это хитовый подход. Если вы хотите отменить буфер данных, передаваемых по каналу, используйте любой из методов, описанных в этих ответах: http://stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe nagul 15 лет назад 6
Исходя из предложения @ nagul, вот вызов, который работал для меня: `tail -f development.log | stdbuf -oL -eL grep "что-то редкое" | beep` GuitarPicker 7 лет назад 1
Используйте `read -r`, чтобы избежать дублирования обратной косой черты, и` printf '% s \ 007 \ n' "$ a" `, чтобы избежать интерпретации процента выхода в выходных данных. Я также не думаю, что хвостовой вызов необходим (и я не уверен, что Bash его оптимизирует) - просто делайте `пока читаете…; делать …; сделано вместо Lucas Werkmeister 6 лет назад 0
9
Sam Stokes

Экран 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 удивительно универсален - я настоятельно рекомендую прочитать об этом.

Это не будет звучать только на «что-то редкое», не так ли? nagul 15 лет назад 1
Было бы, если бы все, что происходило в этом конкретном окне, было `tail -f yourfile.log | grep что-то \ редкое`, а не просто `tail -f logfile` David Spillett 15 лет назад 0
Ой, я не заметил, что он хотел только сигнал «что-то редкое». Отредактировано, чтобы отразить это. Grep сработал бы, но тогда он не увидел бы остальную часть журнала, только редкие строки - насколько я понимаю, он хочет иметь возможность просматривать весь журнал, прокручивающийся мимо, но быть предупрежденным о конкретных событиях. Sam Stokes 15 лет назад 0
1
A reader

Вы можете остановить буферизацию вывода в команде 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
oanoss

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

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

You could use sed to add the control-G as follows:

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

or just on rare lines, without using grep, as follows:

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

which says: on the lines where something rare occurs, substitute everything for the same stuff with control-G tacked on the end, and print (but don't print the non-matching lines). Works great!

0
Ivan Vučica

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

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
nagul

В предыдущей работе я не мог получить надежного наблюдателя с помощью только команды 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 ''` 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чтобы гарантировать, что строки, добавленные в файл после того, как мы проверили его, не перекосят фрагмент файла, который проверяется в этом цикле.

Похожие вопросы