¿Por qué el siguiente comando no produce ningún resultado?
$ tail -f /etc/passwd | tail
Después de leer sobre el almacenamiento en búfer , intenté lo siguiente en vano:
$ tail -f /etc/passwd | stdbuf -oL tail
Tenga en cuenta que lo siguiente produce resultados:
$ tail /etc/passwd | tail
Entonces, esto:
$ tail -f /etc/passwd | head
Estoy usando la versión de cola 8.21 (GNU coreutils).

Respuestas:
Pensé que había visto todo en UNIX. Esta pregunta me sacó de mi presunción. ¡Qué gran pregunta!
tailmuestra las últimas X líneas.tail -fhace 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,
taildebe poder ubicar el final del archivo. Sitailno puede encontrar el final del archivo, no puede mostrar las últimas líneas X, porque "último" no está definido. Entonces, ¿qué hacetailen este caso? Espera hasta que encuentre el final del archivo.Considera esto:
Esto nunca parece avanzar, porque nunca hay un final definitivo desde el archivo
chatter.Obtiene el mismo comportamiento si solicita
taildarle las últimas líneas de una tubería del sistema de archivos. Considerar:stdbufevitar 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 elfile_linescomentario de la función dice:Y esa es la magia. Necesita un final de archivo para que la cola funcione en cualquier configuración.
headno tiene esa restricción, solo necesita un inicio de archivo (que podría no tener, intentehead test.pipe). Transmitir como herramientas orientadassedyawkno requieren de un comienzo o al final del archivo: trabajan en los tampones.fuente
tail -fLa cola es realmente algo desconocido en el presente, entonces, ¿cómo deberíatailsaberlo el próximo ? Por otro ladotail -f, la cabeza es algo ya conocido y que podría ser procesado.O para decirlo de manera más simple:
tailes relativo al final del archivo, pero el flujo de salida detail -fno obtuvo EOF (al menos no antes de su finalización).Si encuentra el
tailpid del primer y lo mata, entonces debería ver el resultado del segundo.fuente
Respuesta técnica
Cuando se ejecuta con una secuencia como entrada,
tailmantiene unnbúfer de línea que se llena a medida que lee la secuencia, pero no puede generar esas líneas hasta que llega al final de la secuencia, es decir, recibe unEOFcódigo especial cuando intenta leer desde la entrada corriente. La invocacióntail -fno sale, por lo tanto, nunca cerrará su flujo, lo que hace imposible, por ejemplo, devolver las 10 últimas líneas de ese flujo.fuente
La función de
tailes mostrar la última parte - "cola" - de la entrada o archivo. (La opción-fes sobre lo que hace más tarde, por lo que eso no es relevante aquí).Pensemos en un archivo:
¿Cuál es la última parte de un archivo ?
Digamos que son las últimas n líneas de un archivo.
Cuando leemos la línea
idel archivo de entrada, ¿cómo decidir si debe imprimirse o no?No sabemos si está en la última parte, porque no sabemos cuál será la última línea. Entonces no podemos imprimirlo ahora.
Necesitamos mantener la línea hasta que quede claro que es parte de las últimas
nlíneas, o que ya no puede ser parte de ella, porque conocemosnmás líneas.Si ahora llegamos al final del archivo , sabemos que las últimas
nlíneas que guardamos son, de hecho, las últimasnlíneas del archivo.Ahora, en el caso de
el primero
taillee el archivo, y luego espera obtener más datos de él, para escribir eso también. Por lo tanto, no indicará el final del archivo a la segunda cola cuando llegue al final del archivo que lee. Sin eso, el segundotailnunca recibe una notificación del final del archivo, por lo que nunca puede averiguar cuáles son las últimas líneas que debe imprimir.fuente