Utilisation de la module sh (pip install sh) :
from sh import tail
# runs forever
for line in tail("-f", "/var/log/some_log_file.log", _iter=True):
print(line)
[mise à jour]
Puisque sh.tail avec _iter
=True est un générateur, vous pouvez :
import sh
tail = sh.tail("-f", "/var/log/some_log_file.log", _iter=True)
Ensuite, vous pouvez "getNewData" avec :
new_data = tail.next()
Notez que si le tampon de queue est vide, il se bloquera jusqu'à ce qu'il y ait plus de données (d'après votre question, ce que vous voulez faire dans ce cas n'est pas clair).
[mise à jour]
Cela fonctionne si vous remplacez -f par -F, mais en Python ce serait un verrouillage. Je serais plus intéressé par une fonction que je pourrais appeler pour obtenir de nouvelles données quand je le veux, si c'est possible. - Eli
Un générateur de conteneur plaçant l'appel de la queue à l'intérieur d'une boucle while True et récupérant les éventuelles exceptions d'E/S aura presque le même effet que -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
Si le fichier devient inaccessible, le générateur renvoie None. Cependant, il bloque toujours jusqu'à ce qu'il y ait de nouvelles données si le fichier est accessible. Ce que vous voulez faire dans ce cas n'est pas clair pour moi.
L'approche de Raymond Hettinger semble assez bonne :
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 ''
Ce générateur retournera '' si le fichier devient inaccessible ou s'il n'y a pas de nouvelles données.
[mise à jour]
L'avant-dernière réponse tourne autour du haut du fichier, il semble que chaque fois qu'il manque de données. - Eli
Je pense que la seconde sortira les dix dernières lignes lorsque le processus de queue se terminera, ce qui avec -f
c'est chaque fois qu'il y a une erreur d'E/S. Le site tail --follow --retry
n'est pas loin de cela dans la plupart des cas auxquels je peux penser dans les environnements de type unix.
Peut-être que si vous mettez à jour votre question pour expliquer quel est votre véritable objectif (la raison pour laquelle vous voulez imiter tail --retry), vous obtiendrez une meilleure réponse.
La dernière réponse ne suit pas réellement la queue et lit simplement ce qui est disponible au moment de l'exécution. - Eli
Bien sûr, tail affichera les 10 dernières lignes par défaut... Vous pouvez positionner le pointeur de fichier à la fin du fichier en utilisant file.seek, je laisserai une implémentation correcte comme exercice au lecteur.
À mon avis, l'approche file.read() est bien plus élégante qu'une solution basée sur un sous-processus.