Jeśli chcę tail
plik tekstowy o wielkości 25 GB, czy tail
polecenie odczytuje cały plik?
Ponieważ plik może być rozproszony na dysku, wyobrażam sobie, że musi, ale nie rozumiem dobrze takich elementów wewnętrznych.
Nie, tail
nie odczytuje całego pliku, szuka do końca, a następnie odczytuje bloki do tyłu, aż do osiągnięcia oczekiwanej liczby linii, a następnie wyświetla linie we właściwym kierunku do końca pliku i prawdopodobnie nadal monitoruje plik, jeśli -f
opcja jest używana.
Zauważ jednak, że tail
nie ma wyboru, jak tylko odczytać wszystkie dane, jeśli nie są widoczne, na przykład podczas odczytu z potoku.
Podobnie, gdy zostanie poproszony o wyszukanie wierszy zaczynających się od początku pliku, przy użyciu tail -n +linenumber
składni lub tail +linenumber
niestandardowej opcji, gdy jest obsługiwana, tail
oczywiście czyta cały plik (chyba że jest przerwany).
tail +n
będzie przeczytać cały plik - najpierw znaleźć odpowiednią liczbę nowych linii, a następnie do wyjścia resztę.tail
implementacje robią to lub robią to poprawnie. Na przykład zajęty 1.21.1tail
jest pod tym względem zepsuty. Zauważ też, że zachowanie zmienia się, gdytail
ing jest stdin i gdzie stdin jest zwykłym plikiem, a początkowa pozycja w pliku nie jest na początku, gdytail
jest wywoływana (jak w{ cat > /dev/null; tail; } < file
)Mogłeś zobaczyć, jak to
tail
działa. Jak można, jeden z moich plikówread
jest wykonywany trzykrotnie i w sumie odczytywanych jest około 10 000 bajtów:źródło
strace
pokazuje, cotail
robią wywołania systemowe po uruchomieniu. Kilka wstępów na temat wywołań systemowych można przeczytać tutaj en.wikipedia.org/wiki/System_call . W skrócie - otwórz - otwiera plik i zwraca uchwyt (3 w tym przykładzie),lseek
pozycje, w których zamierzasz czytać iread
po prostu czyta, a jak widzisz, zwraca liczbę odczytanych bajtów,Jak już wiesz,
tail
po prostu szuka końca pliku (z wywołaniem systemowymlseek
) i działa wstecz. Ale w przytoczonej wyżej uwadze zastanawiasz się, „skąd ogon wie, gdzie na dysku znaleźć koniec pliku?”Odpowiedź jest prosta: ogon nie wie. Procesy na poziomie użytkownika widzą pliki jako ciągłe strumienie, więc wszyscy
tail
mogą wiedzieć, że jest przesunięciem od początku pliku. Ale w systemie plików „i-węzeł” pliku (pozycja katalogu) jest powiązany z listą liczb oznaczających fizyczną lokalizację bloków danych pliku. Kiedy czytasz z pliku, jądro / sterownik urządzenia ustalają, której części potrzebujesz, ustala swoją lokalizację na dysku i pobiera ją za ciebie.To jest coś, do czego mamy systemy operacyjne: więc nie musisz się martwić, gdzie bloki twojego pliku są rozproszone.
źródło
Jeśli
head
lubtail
wydaje się czytać cały plik, prawdopodobnym powodem jest to, że plik zawiera niewiele znaków nowej linii lub nie zawiera ich wcale . Potknąłem się o to kilka miesięcy temu z bardzo dużą (gigabajtami) kroplą JSON, która została serializowana bez żadnych spacji, nawet w ciągach.Jeśli masz głowę / ogon GNU, możesz użyć
-c N
do wydrukowania pierwszego / ostatniego N bajtów zamiast linii , ale niestety nie jest to funkcja POSIX.źródło
Jak widać w wierszu kodu źródłowego 525, można zobaczyć komentarze do implementacji.
źródło