Si quiero tail
un tail
archivo de texto de 25 GB, ¿el comando lee todo el archivo?
Dado que un archivo puede estar disperso en un disco, imagino que tiene que hacerlo, pero no entiendo bien esas cosas internas.
No, tail
no lee todo el archivo, busca hasta el final, luego lee los bloques hacia atrás hasta que se haya alcanzado el número esperado de líneas, luego muestra las líneas en la dirección correcta hasta el final del archivo y posiblemente permanece monitoreando el archivo si -f
se usa la opción.
Sin embargo, tail
tenga en cuenta que no tiene más remedio que leer todos los datos si se proporciona una entrada no buscable, por ejemplo, al leer desde una tubería.
Del mismo modo, cuando se le pide que busque líneas que comienzan desde el principio del archivo, con el uso de la tail -n +linenumber
sintaxis o tail +linenumber
la opción no estándar cuando es compatible, tail
obviamente lee todo el archivo (a menos que se interrumpa).
tail +n
leerá todo el archivo, primero para encontrar el número deseado de nuevas líneas, luego para generar el resto.tail
implementaciones lo hacen o lo hacen correctamente. Por ejemplo, busybox 1.21.1tail
está roto en ese sentido. También tenga en cuenta que el comportamiento varía cuandotail
ing stdin y donde stdin es un archivo normal y la posición inicial en el archivo no es al principio cuandotail
se invoca (como en{ cat > /dev/null; tail; } < file
)Podrías haber visto cómo
tail
funciona tú mismo. Como puede, uno de mis archivosread
se realiza tres veces y en total se leen aproximadamente 10K bytes:fuente
strace
muestra quétail
hacen las llamadas al sistema cuando se ejecuta. Alguna introducción sobre las llamadas al sistema que puede leer aquí en.wikipedia.org/wiki/System_call . Brevemente - abrir - abre un archivo y devuelve un identificador (3 en este ejemplo),lseek
posiciones donde va a leer yread
solo lee y, como puede ver, devuelve cuántos bytes se leen,Como ya sabe,
tail
solo busca el final del archivo (con la llamada al sistemalseek
) y funciona al revés. Pero en el comentario citado anteriormente, se pregunta "¿cómo sabe la cola dónde en el disco encontrar el final del archivo?"La respuesta es simple: Tail no lo sabe. Los procesos a nivel de usuario ven los archivos como flujos continuos, por lo que todo lo que se
tail
puede saber es el desplazamiento desde el inicio del archivo. Pero en el sistema de archivos, el "inodo" del archivo (entrada de directorio) está asociado con una lista de números que denotan la ubicación física de los bloques de datos del archivo. Cuando lees el archivo, el núcleo / el controlador del dispositivo descubre qué parte necesitas, calcula su ubicación en el disco y la busca por ti.Ese es el tipo de cosas para las que tenemos sistemas operativos: para que no tenga que preocuparse por dónde están dispersos los bloques de sus archivos.
fuente
Si
head
otail
parece estar leyendo el archivo completo, una razón probable es que el archivo contiene pocos o ningún carácter de nueva línea . Me tropecé con esto hace unos meses con un blob JSON muy grande (gigabytes) que se había serializado sin espacios en blanco, ni siquiera en cadenas.Si tiene GNU head / tail puede usar
-c N
para imprimir el primer / último N bytes en lugar de líneas , pero desafortunadamente esta no es una característica POSIX.fuente
Como puede ver en la línea de código fuente 525, puede ver los comentarios para la implementación.
fuente