Myślałem, że widziałem wszystko w systemie UNIX. To pytanie wyrwało mnie z zadowolenia z siebie. Cóż za świetne pytanie!
tailpokazuje ostatnie X linii. tail -frobi to samo, ale zasadniczo w nieskończonej pętli: podczas uruchamiania pokaż ostatnie X linii pliku, a następnie używając magii systemu operacyjnego (np. inotify), monitoruj i pokaż nowe linie.
Aby wykonać swoje zadanie, tailmusi być w stanie zlokalizować koniec pliku. Jeśli tailnie można znaleźć końca pliku, nie może wyświetlić ostatnich X linii, ponieważ „ostatni” jest niezdefiniowany. Co więc robi tailw tym przypadku? Czeka, aż znajdzie koniec pliku.
Rozważ to:
$ chatter() { while :; do date; sleep 1; done; }
$ chatter | tail -f
Wydaje się, że nigdy nie robi to postępu, ponieważ nigdy nie ma określonego końca pliku chatter.
Takie samo zachowanie otrzymasz, jeśli poprosisz tailo podanie ostatnich linii z potoku systemu plików. Rozważać:
$ mkfifo test.pipe
$ tail test.pipe
stdbufobejście postrzeganego problemu było szlachetną próbą. Kluczowym faktem jest jednak to, że buforowanie We / Wy nie jest główną przyczyną: brak określonego końca pliku. Jeśli sprawdzisz kod źródłowy tail.c , zobaczysz file_lineskomentarz funkcji o treści:
END_POS to przesunięcie pliku EOF (jeden większy niż przesunięcie ostatniego bajtu).
i to jest magia. Potrzebujesz końca pliku, aby tail działał w dowolnej konfiguracji. headnie ma tego ograniczenia, potrzebuje tylko początku pliku (którego może nie mieć, spróbuj head test.pipe). Narzędzia zorientowane na strumień, takie jak sedi awknie potrzebują ani początku, ani końca pliku: działają na buforach.