8

How do continuously monitor a file that is being continuously overwritten? Specifically, the file contains a single line of text which a background process is repeatedly opening and re-writing.

I was hoping tail -F would work, but it doesn't.

Update: I was hoping this wouldn't be pertinent, but I'm running Mac OS X 10.5.8.

Daryl Spitzer
  • 2,946
  • 9
  • 33
  • 40
  • I wonder if screen could be coerced into doing this with some help from a script of some sort. – Paul Feb 25 '10 at 17:54
  • Seems to work here. Maybe OS X fixed it since? See also `less +F --follow-name` https://unix.stackexchange.com/questions/196168/does-less-have-a-feature-like-tail-follow-name-f – rogerdpack Apr 07 '21 at 17:34
  • Similar question: [linux - Continuously monitor logs with tail that are occasionally rotated - Server Fault](https://serverfault.com/questions/53699/continuously-monitor-logs-with-tail-that-are-occasionally-rotated) ____________________________________________________________________________________________ Same question on ask-Ubuntu site: [redirect - 'tail -F' behaving unexpectedly on truncated file - Ask Ubuntu](https://askubuntu.com/questions/1067550/tail-f-behaving-unexpectedly-on-truncated-file) – user202729 Oct 19 '21 at 15:46

5 Answers5

6

You can use watch to repeat a command execution, so in your case

watch -n 1 cat filename
Dominik
  • 2,198
  • 13
  • 9
  • This won't work on FreeBSD (or anywhere `watch` isn't what you expect it to be), also if the file rotates faster than every `-n` seconds you'll miss stuff... – voretaq7 Feb 25 '10 at 17:03
  • And watch doesn't seem to be on Mac OS X. (Not 10.5.8 at least.) – Daryl Spitzer Feb 25 '10 at 17:44
  • 1
    It works great on Linux though. – Daryl Spitzer Feb 25 '10 at 17:48
  • 1
    I would distrust any solution that involves fixed timing intervals (`watch -n`, anything with `sleep`, the linux `tail` with `-s` > 0). That's also leaving aside my objection to any solution that "only works on [insert platform]" – voretaq7 Feb 25 '10 at 18:49
  • Besides this should be *a little* more CPU-intensive than tail, which should use inotify. – user202729 Oct 19 '21 at 15:44
1

There are better ways to do this, but it'll work

  while true ; do echo -n "`date +%s:` " >> file.log ; cat file >> file.log  ; done 

The file.log file will grow...rapidly...

If you need more features, like to check to see if the contents of the file are equal to the previous contents, you can expand this out into a script. Just comment below and I'll help.

Matt Simmons
  • 20,218
  • 10
  • 67
  • 114
1

On BSD systems (and I believe most other systems) tail -f will reset to the beginning of the file if it sees that the file has been truncated (this sounds like exactly the behavior you want).

On Linux systems the same thing happens, but at least on the Debian box I have laying around tail has a "polling interval", so you need to tell it not to sleep between checks of the file (tail -s 0 -f ...) for it to notice the truncation, otherwise strange things happen (if the file is the same size or smaller when it's written out you get no output, if it's bigger you get everything after tail's current byte-count marker, etc. -- Play with your tail impementation to see how it behaves)


As an alternative on both Linux and BSD systems tail has a -F option (which is like -f but checks to see if the file has been rotated -- i.e. the name points to a different inode number). This won't help you if the file is being truncated as opposed to unlink'd and replaced though.

voretaq7
  • 79,345
  • 17
  • 128
  • 213
1

Poor man's watch:

while true
do
    clear
    cat file
    sleep 1
done

Change the cat if the file is longer than a screenful to something like:

tail -n $((LINES - 4)) file

You could add conditionals to check for a change in the file's timestamp, etc.

Dennis Williamson
  • 60,515
  • 14
  • 113
  • 148
0

You could use the FSEvents API and a small script to monitor the file (or more precisely the directory which contains the file).

joschi
  • 20,747
  • 3
  • 46
  • 50