I want to output a file’s contents while they change, for example if I have the file foobar and I do:
magic_command foobar
The current terminal should display the file’s contents and wait until, I don’t know, I press ^C.
Then if from another terminal I do:
echo asdf >> foobar
The first terminal should display the newly added line in addition to the original file contents (of course, given that I didn’t press ^C).
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
You can use tail command with -f :
tail -f /var/log/syslog
It’s good solution for real time show.
Method 2
If you want to show a short file, that fits on one terminal screen,
and what is changing is possibly the whole file, you could use watch:
watch cat example.txt
Every 2.0s: cat example.txt Sun Aug 3 15:25:20 2014 Some text another line
It shows the whole file every 2 seconds by default, including an optional header:
The option -d (--differences) will highlight changes from previous version of the output, or from the first version.
Method 3
less has a follow mode similar to tail -f – just hit F when you have it open.
Method 4
When I need to detect file changes and do something other than what tail -f filename does, I’ve used inotifywait in a script to detect the change and act upon it. An example of use is shown below. See man inotifywait for other event names and switches. You may need to install the inotify-tools package, for example via sudo apt-get install inotify-tools.
Here’s the example script, called exec-on-change:
#!/bin/sh # Detect when file named by param $1 changes. # When it changes, do command specified by other params. F=$1 shift P="$*" # Result of inotifywait is put in S so it doesn't echo while S=$(inotifywait -eMODIFY $F 2>/dev/null) do # Remove printf if timestamps not wanted printf "At %s: n" "$(date)" $P done
In two consoles I entered commands as follows (where A> means entry in console A, and B> means entry in console B.)
A> rm t; touch t B> ./exec-on-change t wc t A> date >>t A> date -R >>t A> date -Ru >>t A> cat t; rm t
The following output from cat t appeared in console A:
Thu Aug 16 11:57:01 MDT 2012 Thu, 16 Aug 2012 11:57:04 -0600 Thu, 16 Aug 2012 17:57:07 +0000
The following output from exec-on-change appeared in console B:
At Thu Aug 16 11:57:01 MDT 2012: 1 6 29 t At Thu Aug 16 11:57:04 MDT 2012: 2 12 61 t At Thu Aug 16 11:57:07 MDT 2012: 3 18 93 t
The exec-on-change script terminated when I rm‘d t.
Method 5
I have three solutions:
1) tail -f is a good idea
2) we have also tailf to use
3) third one is a bash script:
#!/bin/bash
GAP=10 #How long to wait
LOGFILE=$1 #File to log to
if [ "$#" -ne "1" ]; then
echo "USAGE: `basename $0` <file with absolute path>"
exit 1
fi
#Get current long of the file
len=`wc -l $LOGFILE | awk '{ print $1 }'`
echo "Current size is $len lines."
while :
do
if [ -N $LOGFILE ]; then
echo "`date`: New Entries in $LOGFILE: "
newlen=`wc -l $LOGFILE | awk ' { print $1 }'`
newlines=`expr $newlen - $len`
tail -$newlines $LOGFILE
len=$newlen
fi
sleep $GAP
done
exit 0
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0