I\'d like to make the output of tail -F or something similar available to me in Python without blocking or locking. I\'ve found some really old code to do that here, but I\'
The only portable way to tail -f
a file appears to be, in fact, to read from it and retry (after a sleep
) if the read
returns 0. The tail
utilities on various platforms use platform-specific tricks (e.g. kqueue
on BSD) to efficiently tail a file forever without needing sleep
.
Therefore, implementing a good tail -f
purely in Python is probably not a good idea, since you would have to use the least-common-denominator implementation (without resorting to platform-specific hacks). Using a simple subprocess
to open tail -f
and iterating through the lines in a separate thread, you can easily implement a non-blocking tail
operation in Python.
Example implementation:
import threading, Queue, subprocess
tailq = Queue.Queue(maxsize=10) # buffer at most 100 lines
def tail_forever(fn):
p = subprocess.Popen(["tail", "-f", fn], stdout=subprocess.PIPE)
while 1:
line = p.stdout.readline()
tailq.put(line)
if not line:
break
threading.Thread(target=tail_forever, args=(fn,)).start()
print tailq.get() # blocks
print tailq.get_nowait() # throws Queue.Empty if there are no lines to read