Verwenden des sh-Moduls (pip install sh):
from sh import tail
for line in tail("-f", "/var/log/some_log_file.log", _iter=True):
print(line)
[aktualisieren]
Da sh.tail with _iter
= True ein Generator ist, können Sie:
import sh
tail = sh.tail("-f", "/var/log/some_log_file.log", _iter=True)
Dann können Sie "getNewData" mit:
new_data = tail.next()
Beachten Sie, dass der Endpuffer, wenn er leer ist, blockiert wird, bis weitere Daten vorhanden sind (aus Ihrer Frage geht nicht hervor, was Sie in diesem Fall tun möchten).
[aktualisieren]
Dies funktioniert, wenn Sie -f durch -F ersetzen, aber in Python wird es gesperrt. Ich wäre mehr an einer Funktion interessiert, die ich aufrufen könnte, um neue Daten zu erhalten, wenn ich möchte, wenn dies möglich ist. - Eli
Ein Containergenerator, der den Tail-Aufruf innerhalb einer while-True-Schleife platziert und eventuelle E / A-Ausnahmen abfängt, hat fast den gleichen Effekt wie -F.
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
Wenn auf die Datei nicht mehr zugegriffen werden kann, gibt der Generator None zurück. Es wird jedoch weiterhin blockiert, bis neue Daten vorliegen, wenn auf die Datei zugegriffen werden kann. Es bleibt mir unklar, was Sie in diesem Fall tun möchten.
Der Ansatz von Raymond Hettinger scheint ziemlich gut zu sein:
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 ''
Dieser Generator gibt '' zurück, wenn auf die Datei nicht mehr zugegriffen werden kann oder wenn keine neuen Daten vorhanden sind.
[aktualisieren]
Die vorletzte Antwort wird an der Spitze der Datei angezeigt, wenn die Daten ausgehen. - Eli
Ich denke, die zweite gibt die letzten zehn Zeilen aus, wenn der Endprozess endet, und -f
zwar immer dann, wenn ein E / A-Fehler vorliegt. Das tail --follow --retry
Verhalten ist in den meisten Fällen, die ich mir in Unix-ähnlichen Umgebungen vorstellen kann, nicht weit davon entfernt.
Wenn Sie Ihre Frage aktualisieren, um zu erklären, was Ihr eigentliches Ziel ist (der Grund, warum Sie die Schwanzwiederholung imitieren möchten), erhalten Sie möglicherweise eine bessere Antwort.
Die letzte Antwort folgt nicht dem Schwanz und liest lediglich, was zur Laufzeit verfügbar ist. - Eli
Natürlich zeigt tail standardmäßig die letzten 10 Zeilen an ... Sie können den Dateizeiger mit file.seek am Ende der Datei positionieren. Ich überlasse dem Leser eine ordnungsgemäße Implementierung als Übung.
Meiner Meinung nach ist der file.read () -Ansatz weitaus eleganter als eine auf Subprozessen basierende Lösung.
subprocess.call(["tail", "-F", filename])