Continuous Monitoring With Tail Fails

If you can’t get tail command to continuously monitor a file, then read on. I was working on a script yesterday, a part of which depended on continuous monitoring of a text file. I had used our trusty old “tail” command for this but while testing by manually putting in some data into the file, it was failing but curiously it was working fine when used in actual scenario. Befuddled, I did a simple test. I created a simple text file “a.txt” with a few lines of data and then ran the following command.

tail -f a.txt

It showed the last few lines of the file and kept waiting. So far so good. Then I opened the file in vim editor, wrote a few more lines, saved the file and then waited but nothing in the window that was running the tail command. Thinking that the data might be buffered and not flushed to the disc yet, I ran the sync command but still nothing.

Then I got a hint that when I used the “-F” or “–follow=name” option instead of “-f”, the tail command was able to detect the change just fine, the only problem being that in this mode, it prints the last few lines again, not just the newly added line. The main difference in these new options is that tail command tracks the file for changes by its name and not by the file descriptor, and then it dawned on me. The problem is not in the tail command but my testing method itself. When I save the file opened in vim, it creates a new file with a new inode while the one opened by tail is still the old one (which is now a temporary file which has actually been deleted). When I quit tail, then the kernel deletes the file automatically. This is also confirmed by running “lsof | grep a.txt” (lsof lists the open files and then we find the ones related to a.txt). The output shown is;

tail      11966   shantanu    3r      REG                8,6        8     224954 /home/shantanu/dev/perl/plot/a.txt~ (deleted)

vim       12576   shantanu    9u      REG                8,6    12288     210918 /home/shantanu/dev/perl/plot/.a.txt.swp

which shows what we had discussed above. This gets worked around when I use the -F option because then tail periodically reopens the file by name and reads it again, thus bypassing the above issue. Then I simply tried running tail again on the same file and doing something like “echo abc » a.txt” and I could see the behaviour as expected with tail immediately detecting the change and displaying it in its window. Hope this helps if you have been pulling out your hair thinking you have gone crazy as your favourite little tool that you have been using for so many years has suddenly stopped working and no one else apart from you is even complaining :P

See also