Si je veux tail
un fichier texte de 25 Go, la tail
commande lit-elle l'intégralité du fichier?
Étant donné qu’un fichier peut être dispersé sur un disque, j’imagine qu’il doit le faire, mais je ne comprends pas bien ces éléments internes.
Non, tail
ne lit pas tout le fichier, il cherche la fin puis lit les blocs à l'envers jusqu'à atteindre le nombre de lignes attendu, puis affiche les lignes dans le bon sens jusqu'à la fin du fichier et reste éventuellement en veille. fichier si l' -f
option est utilisée.
Notez cependant que tail
n’a pas d’autre choix que de lire l’ensemble des données si une entrée non recherchée est fournie, par exemple lors de la lecture d’un canal.
De même, lorsqu'on lui demande de rechercher des lignes à partir du début du fichier, avec l'aide de la tail -n +linenumber
syntaxe ou de tail +linenumber
l'option non standard lorsque pris en charge, tail
lit intégralement le fichier (sauf si interrompu).
tail +n
lira l’ensemble du fichier - d’abord pour trouver le nombre souhaité de nouvelles lignes, puis pour afficher le reste.tail
implémentations ne le font pas ou ne le font pas correctement. Par exemple, busybox 1.21.1tail
est cassé à cet égard. Notez également que le comportement varie lorsquetail
stdin est utilisé et que stdin est un fichier normal et que la position initiale dans le fichier n’est pas au début lorsqu’elletail
est invoquée (comme dans{ cat > /dev/null; tail; } < file
)Vous auriez pu voir comment ça
tail
marche vous-même. Comme vous pouvez le faire pour un de mes fichiersread
est fait trois fois et au total environ 10K octets sont lus:la source
strace
montre ce quetail
font les appels système lors de l'exécution. Vous pouvez lire un peu d’introduction sur les appels système en.wikipedia.org/wiki/System_call . En bref - ouvrir - ouvre un fichier et retourne un descripteur (3 dans cet exemple), leslseek
positions où vous allez lire etread
simplement lire et comme vous pouvez le voir, combien d'octets lus sont lus,Comme vous le savez maintenant,
tail
cherche simplement la fin du fichier (avec l'appel systèmelseek
), et fonctionne à l'envers. Mais dans la remarque citée ci-dessus, vous vous demandez "comment tail ne sait où sur le disque trouver la fin du fichier?"La réponse est simple: la queue ne sait pas. Les processus au niveau utilisateur voient les fichiers comme des flux continus, de sorte que tout
tail
peut être connu, c'est le décalage par rapport au début du fichier. Mais dans le système de fichiers, "l'inode" du fichier (entrée de répertoire) est associé à une liste de nombres indiquant l'emplacement physique des blocs de données du fichier. Lorsque vous lisez le fichier, le noyau / le pilote de périphérique détermine la partie dont vous avez besoin, détermine son emplacement sur le disque et le recherche à votre place.C'est le genre de chose pour laquelle nous avons un système d'exploitation: vous n'avez donc pas à vous soucier de la répartition des blocs de votre fichier.
la source
Si
head
outail
semble lire tout le fichier, cela tient probablement au fait que le fichier contient peu ou pas de caractères de nouvelle ligne . J'y ai trébuché il y a quelques mois avec un très gros blob JSON (sérialisé) sérialisé sans aucun espace, même pas dans des chaînes.Si vous avez une tête / queue GNU, vous pouvez utiliser
-c N
pour imprimer le premier / dernier N octets au lieu de lignes , mais malheureusement, ce n’est pas une fonctionnalité POSIX.la source
Comme vous pouvez le voir dans la ligne de code source 525, vous pouvez voir les commentaires pour l'implémentation.
la source