Pensé que había visto todo en UNIX. Esta pregunta me sacó de mi presunción. ¡Qué gran pregunta!
tail
muestra las últimas X líneas. tail -f
hace lo mismo, pero esencialmente en un bucle infinito: en el inicio, muestra las últimas X líneas del archivo, luego usa algo de magia del sistema operativo (como inotify), supervisa y muestra nuevas líneas.
Para hacer su trabajo, tail
debe poder ubicar el final del archivo. Si tail
no puede encontrar el final del archivo, no puede mostrar las últimas líneas X, porque "último" no está definido. Entonces, ¿qué hace tail
en este caso? Espera hasta que encuentre el final del archivo.
Considera esto:
$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f
Esto nunca parece avanzar, porque nunca hay un final definitivo desde el archivo chatter
.
Obtiene el mismo comportamiento si solicita tail
darle las últimas líneas de una tubería del sistema de archivos. Considerar:
$ mkfifo test.pipe
$ tail test.pipe
stdbuf
evitar el problema percibido fue un intento noble. Sin embargo, el hecho clave es que el almacenamiento en búfer de E / S no es la causa raíz: la falta de un fin de archivo definitivo sí lo es. Si revisa el código fuente tail.c , verá que el file_lines
comentario de la función dice:
END_POS es el desplazamiento del archivo de EOF (uno más grande que el desplazamiento del último byte).
Y esa es la magia. Necesita un final de archivo para que la cola funcione en cualquier configuración. head
no tiene esa restricción, solo necesita un inicio de archivo (que podría no tener, intente head test.pipe
). Transmitir como herramientas orientadas sed
y awk
no requieren de un comienzo o al final del archivo: trabajan en los tampones.