I'm trying to display a new line that was added to the file.
So imagine that I have a sample_file.txt
:
1. line 1
2. line 2
3. line 3
I want to check if this file got a new line, and than display that line (without printing all the file again)
#!/usr/bin/python
import os
import pyinotify
from datetime import datetime
import time
PATH = os.path.join(os.path.expanduser('~/'), 'sample_file.txt')
m = pyinotify.WatchManager()
m.add_watch(PATH, pyinotify.ALL_EVENTS, rec=True)
notifier = pyinotify.Notifier(m, pyinotify.ProcessEvent(), 0, 0, 100)
f = open(PATH)
for line in f.readlines():
print line
while True:
time.sleep(5)
try:
if notifier.check_events():
# RIGHT HERE:
# HOW TO DO SOMETHING LIKE
# f.last() ???
print f.next()
else:
print 'waiting for a line....'
except KeyboardInterrupt:
notifier.stop()
break
What I was thinking is to read all the lines somewhere before while loop, and than print the next line, but something wrong in my code, and it checks for f.next()
right after it comes to the loop.
I'll address the two issues:
tail
on a file,pyinotify
module.Tail on a file
In your code, you need to:
read
orreadlines
,seek
.This translates for example into:
You can find more examples here, although some do not address additions to the file which do not end with a newline:
And some alternatives here How can I tail a log file in Python?
Pyinotify loop
You should also move your code inside
pyinotify
's event handlers as explained in the documentation.check_events
returnsTrue
if there are events to be processed, but it does not actually process the events, so by itself it will always returnTrue
until events have been processed.Also, try and avoid
while
/sleep
loops. Inotify adds the capability to handle an event as soons as it is received, without compromising resources. Awhile
/sleep
loop will be less reactive.Below are the two first methods form the Short Tutorial on
pyinotify
.1. Monitoring endlessly
This is the preferred method if you have no other event loop, as it will be the most reactive:
2. Monitoring periodically
If you already have a processing loop, then it's just a matter of calling
process_events
periodically. TheEventHandler
class is the same as in method 1, but now instead of callingnotifier.loop()
we add a small timeout to the notifier, and implement our own event loop.