tags:

views:

597

answers:

5

I want to run a command as soon as a certain text appears in to a log file. How do I do it in bash?

+11  A: 

Use command

tail -f file.log | grep --line-buffered "my pattern" | while read line
do
  echo $line
done

The --line-buffered is the key here, otherwise the read will fail.

ketorin
+1  A: 

This should work even without GNU grep:

tail -f -n 0 logfile.out | nawk '/pattern/ {system("echo do something here")}'

edit: Added "-n 0" so that only new occurences of the text will be matched.

matli
+4  A: 

Using only tail:

tail -f file.log | while read line; do if [[ $line == *text* ]]; then
    mycommand
fi; done
Bruno De Fraine
A: 

I like matli's answer. Bruno De Fraine's answer is also good in that it uses only shell ccommands, not other programs (like awk). It suffers from the problem that the entire line must match the magic string. It's not clear from the question that's part of the requirment.

I would modify it a tiny bit to deal with the "as soon as" clause in the original question

logfile_generator | tee logfile.out | nawk '/pattern/ {system("echo do something here")}'

where logfile_generator is the program that is generating the log file in the first place. This modification executes the "something" as soon as the magic string is located.

mxg
My solution matches any line that contains "text" (that's what the pattern *text* does), not only lines equal to "text". See the description of the [[ ]] compound and == in the Bash manual.
Bruno De Fraine
+1  A: 

Also you might look at inotail, a replacement for tail -f which uses the inotify framework to wake up only when the file you're interested in has changed. The usual tail -f just sleeps for short periods of time between polling, which is an effective but not very efficient solution.

tialaramex