I want my PC to make a system beep on every tail event

I have the following command

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

is there an easy way like pipeing it to somthing that beeps? like

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

if so will the grep output still be shown?

  • there is a beep program with is in the default repo for debian and variants just apt-get install beep but it doesn't work with the piping this way – Jakob Cosoroaba Sep 7 '09 at 13:51

Just define beep as following:

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

Then, you can use your command:

tail -f development.log | grep "something rare" | beep
  • 1
    sorry but this is not working, it doesn't beep or prints anything – Jakob Cosoroaba Sep 7 '09 at 13:49
  • 4
    Although direct output of tail -f is immediate, it gets buffered as soon as it goes through a pipe. You have to wait for enough "something rare" before observing anything. – mouviciel Sep 7 '09 at 15:00
  • You could pass the output through sed or similar (between tail and grep) to with a regexp replace the something rare with itself many times. How many times it needs to be done depends on how much the pipe is buffered. – David Spillett Sep 7 '09 at 19:57
  • 6
    @David - That is a hit-and-miss approach. If you want to unbuffer the data passed via a pipe, use any of the methods described in these answers: stackoverflow.com/questions/1000674/turn-off-buffering-in-pipe – nagul Sep 8 '09 at 16:28
  • 2
    Going off of @nagul's suggestion, here is the invocation that worked for me: tail -f development.log | stdbuf -oL -eL grep "something rare" | beep – GuitarPicker Jan 25 '17 at 17:08

GNU screen has a built-in feature to beep when a given window changes: see the relevant section of the man page.

Headline summary:

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

As pointed out in comments, this will beep on every new log entry, not just those that match "something rare", so this doesn't do quite what the OP asked for. Still a useful trick to know IMHO.

You can get the best of both worlds by opening two screen windows (<C-a> c to open a window, <C-a> <C-a> to toggle between two windows):

  1. monitored, with tail -f yourfile.log | grep 'something rare'
  2. unmonitored, with a plain tail -f yourfile.log

Then you can sit watching the log scroll past in window 2, and you'll get beeped from window 1 when "something rare" occurs.

screen is awesomely versatile - I highly recommend reading up on it.

  • 1
    That wouldn't beep only on "something rare", would it? – nagul Sep 7 '09 at 19:06
  • 1
    It would if all that was happening in that particular window is tail -f yourfile.log | grep something\ rare rather than just the tail -f logfile – David Spillett Sep 7 '09 at 19:58
  • Oops, I didn't notice that he only wanted a beep on something rare. Edited to reflect this. The grep would work, but then he wouldn't see the rest of the log, only the rare lines - as I understand it he wants to be able to watch the whole log scrolling past, but be alerted on specific events. – Sam Stokes Sep 8 '09 at 9:38

You can stop the output from being buffered in the grep command. See man grep for details.

You can pipe the grep output into beep.

The following example is from man beep...

   As part of a log-watching pipeline

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

There's a lot of good stuff in those manuals. If only we didn't have to read them to find it. ;-)


The watch command has an --beep option, and you can set the polling interval as well, but the standard with 2 sec should be ok

watch --beep 'tail development.log | grep "something rare"'
  • 1
    Note, watch works by running your parameter/command every (interval) sections then coming the results to the previous run. Thus you'll want to use the normal version of the tail command, instead of using tail -f – RyanWilcox Aug 28 '12 at 19:14
  • This didn't work for me (despite adding watch --beep and wrapping my tail/grep, I still didn't get a beep). – machineghost Nov 1 '18 at 22:13

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!


Hm, tricky. We could perhaps do something like this?

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

Or in your case

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

It seems to be doing some buffering though. I'll look if there's a way to turn off this buffering by the for loop.

Apparently, you should be able to adjust pipe's buffering by using ulimit -p but that keeps complaining about Invalid argument to me. I've also found a post that claims you need to recompile kernel to change this limit.


In a previous job, I couldn't get a reliable watcher with just command-fu, so I had a wrapper script like the one below, which inspected the file every poll_duration seconds and grepped the new lines for the interested phrase.



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 ]
        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
        sleep $poll_duration

This was on a Unix machine. On Linux, you can go one better by using its inotify filewatcher interface. If this package (inotify-tools on Ubuntu) is present, replace

sleep $poll_duration 


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

This call blocks till the file is modified. The blocking version is almost as efficient as what you'd get with the tail -f version if pipe could be configured to work without buffering.

Note: The script first does a head --lines=$new_linecount to ensure that lines added to the file after we checked it do not skew the chunk of the file that gets checked in this loop.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.