Je pensais avoir tout vu dans UNIX. Cette question m'a giflé de ma suffisance. Quelle belle question!
tail
montre les dernières X lignes. tail -f
fait la même chose, mais essentiellement dans une boucle infinie: au démarrage, montre les X dernières lignes du fichier, puis en utilisant une magie de système d’exploitation (comme inotify), surveille et affiche de nouvelles lignes.
Pour faire son travail, tail
il faut pouvoir localiser la fin du fichier. Si tail
vous ne trouvez pas la fin du fichier, il ne peut pas afficher les X dernières lignes, car "last" n'est pas défini. Alors, que fait tail
-on dans ce cas? Il attend jusqu'à ce qu'il trouve la fin du fichier.
Considère ceci:
$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f
Cela ne semble jamais progresser, car il n’existe jamais de fin de fichier définitive chatter
.
Vous obtenez le même comportement si vous demandez tail
à vous donner les dernières lignes d'un canal de système de fichiers. Considérer:
$ mkfifo test.pipe
$ tail test.pipe
stdbuf
contourner le problème perçu était une noble tentative. Cependant, l’essentiel est que la mise en mémoire tampon des E / S ne soit pas la cause première: il n’ya pas de fin de fichier définie. Si vous extrayez le code source tail.c , le file_lines
commentaire de la fonction se lit comme suit:
END_POS correspond au décalage de fichier de EOF (supérieur à celui du dernier octet).
et c'est la magie. Vous avez besoin d'une fin de fichier pour que tail puisse fonctionner dans n'importe quelle configuration. head
n'a pas cette restriction, il faut juste un début de fichier (ce qui pourrait ne pas l'avoir, essayez head test.pipe
). Les outils orientés flux tels que sed
et awk
ne nécessitent ni début ni fin de fichier: ils travaillent sur des tampons.