Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Using the <a href="http://amoffat.github.io/sh/">sh module</a> (pip install sh):</p> <pre><code>from sh import tail # runs forever for line in tail("-f", "/var/log/some_log_file.log", _iter=True): print(line) </code></pre> <p>[update]</p> <p>Since sh.tail with <code>_iter</code>=True is a generator, you can:</p> <pre><code>import sh tail = sh.tail("-f", "/var/log/some_log_file.log", _iter=True) </code></pre> <p>Then you can "getNewData" with:</p> <pre><code>new_data = tail.next() </code></pre> <p>Note that if the tail buffer is empty, it will block until there is more data (from your question it is not clear what you want to do in this case).</p> <p>[update]</p> <blockquote> <p>This works if you replace -f with -F, but in Python it would be locking. I'd be more interested in having a function I could call to get new data when I want it, if that's possible. – Eli</p> </blockquote> <p>A container generator placing the tail call inside a while True loop and catching eventual I/O exceptions will have almost the same effect of -F.</p> <pre><code>def tail_F(some_file): while True: try: for line in sh.tail("-f", some_file, _iter=True): yield line except sh.ErrorReturnCode_1: yield None </code></pre> <p>If the file becomes inaccessible, the generator will return None. However it still blocks until there is new data if the file is accessible. It remains unclear for me what you want to do in this case.</p> <p>Raymond Hettinger approach seems pretty good:</p> <pre><code>def tail_F(some_file): first_call = True while True: try: with open(some_file) as input: if first_call: input.seek(0, 2) first_call = False latest_data = input.read() while True: if '\n' not in latest_data: latest_data += input.read() if '\n' not in latest_data: yield '' if not os.path.isfile(some_file): break continue latest_lines = latest_data.split('\n') if latest_data[-1] != '\n': latest_data = latest_lines[-1] else: latest_data = input.read() for line in latest_lines[:-1]: yield line + '\n' except IOError: yield '' </code></pre> <p>This generator will return '' if the file becomes inaccessible or if there is no new data.</p> <p>[update]</p> <blockquote> <p>The second to last answer circles around to the top of the file it seems whenever it runs out of data. – Eli </p> </blockquote> <p>I think the second will output the last ten lines whenever the tail process ends, which with <code>-f</code> is whenever there is an I/O error. The <code>tail --follow --retry</code> behavior is not far from this for most cases I can think of in unix-like environments.</p> <p>Perhaps if you update your question to explain what is your real goal (the reason why you want to mimic tail --retry), you will get a better answer.</p> <blockquote> <p>The last answer does not actually follow the tail and merely reads what's available at run time. – Eli</p> </blockquote> <p>Of course, tail will display the last 10 lines by default... You can position the file pointer at the end of the file using file.seek, I will left a proper implementation as an exercise to the reader.</p> <p>IMHO the file.read() approach is far more elegant than a subprocess based solution.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload