3

Possible Duplicate:
tail -f in python with no time.sleep

I am trying to monitor a log file that is being written to (like tail -f), and I can't figure out how to make readline() block once it reaches eof. All of my googling has only turned up solutions to make things NON-blocking. Does anyone know a way to make a call like this block, so I DON'T have to poll? (I'm perfectly capable of polling and sleeping already, so if you suggest that I'm going to rate you down.)

fh = open('logfile')
# I only want new output, so seek to the end of the file
fh.seek(-1,2)
while True:
   # I want this to block until the file has new output, 
   # but it sees eof and returns '' immediately
   line = fh.readline()
   # ... process the line
Community
  • 1
  • 1
Nathan Stocks
  • 2,096
  • 3
  • 20
  • 31
  • 4
    You *do* know that `tail -f` polls, right? – Ignacio Vazquez-Abrams Jan 14 '11 at 19:04
  • Definite duplicate of [tail -f in python with no time.sleep](http://stackoverflow.com/questions/1475950/tail-f-in-python-with-no-time-sleep) but with an attitude... Voting to close... – dawg Jan 14 '11 at 19:56
  • If you're on linux, you can check out pyinotify http://pyinotify.sourceforge.net/. I guess technically it polls too, but it does it with the help of the kernel. – Falmarri Jan 14 '11 at 20:10
  • If you're on linux, you can check out pyinotify http://pyinotify.sourceforge.net/. I guess technically it polls too, but it does it with the help of the kernel. – Falmarri Jan 14 '11 at 20:11
  • Sheesh, all those searches beforehand and it was still a duplicate! :-/ – Nathan Stocks Jan 26 '11 at 03:01

1 Answers1

0

You can't really 'block without polling'. You have to check if the file has new data for you at some point. When you write constantly updating processes, you have to poll eventually, unless you're writing ISRs (interrupt service routines) in assembly. Even then, the CPU is constantly polling for any pending interrupts.

Here's your code that checks the file for new data every second. This keeps the CPU usage minimal.

fh = open('logfile')
# I only want new output, so seek to the end of the file
fh.seek(-1,2)
# 'while True' is sort of bad style unless you have a VERY good reason.
# Use a variable. This way you can exit nicely from the loop
done = False 
while not done:
   # I want this to block until the file has new output, 
   # but it sees eof and returns '' immediately
   line = fh.readline()
   if not line:
       time.sleep(1)
       continue
   # ... process the line
       #... if ready to exit:
           done = True
Aphex
  • 7,390
  • 5
  • 33
  • 54
  • 2
    You definetely can block without polling. Reading from serial devices or pipes usually involves blocking read. Basic I/O calls of C for example are usually blocking. However, python's file object returned by `open` isn't. – dronus Aug 30 '16 at 17:02