Если я хочу tail
текстовый tail
файл размером 25 ГБ, команда читает весь файл?
Поскольку файл может быть разбросан по диску, я полагаю, что это необходимо, но я плохо разбираюсь в таких внутренностях.
Нет, tail
не читает весь файл, он стремится к концу, затем читает блоки назад, пока не будет достигнуто ожидаемое количество строк, затем отображает строки в правильном направлении до конца файла и, возможно, продолжает отслеживать файл, если -f
опция используется.
Однако обратите внимание, что у tail
него нет выбора, кроме как прочитать все данные, если они предоставлены без возможности поиска, например, при чтении из канала.
Точно так же, когда его просят искать строки, начинающиеся с начала файла, с использованием tail -n +linenumber
синтаксиса или tail +linenumber
нестандартной опции, когда поддерживается, tail
очевидно, читает весь файл (если он не прерван).
tail +n
будет прочитан весь файл - сначала найти нужное количество новых строк, затем вывести остальные.tail
реализации делают это или делают это правильно. Например, busybox 1.21.1 неtail
работает в этом отношении. Также обратите внимание, что поведение меняется при использованииtail
stdin и где stdin является обычным файлом, а начальная позиция в файле не в начале, когдаtail
вызывается (как в{ cat > /dev/null; tail; } < file
)Вы могли видеть, как
tail
работает сам. Как вы можете, для одного из моих файловread
это делается три раза, и в общей сложности читается примерно 10 Кбайт:источник
strace
показывает, чтоtail
делают системные вызовы при запуске. Некоторое введение в системные вызовы вы можете прочитать здесь en.wikipedia.org/wiki/System_call . Коротко - открыть - открывает файл и возвращает дескриптор (в данном примере 3),lseek
позиции, в которых вы собираетесь читать иread
просто читаете, и, как вы можете видеть, он возвращает количество прочитанных байтов,Как вы теперь знаете,
tail
просто ищет конец файла (с помощью системного вызоваlseek
) и работает в обратном направлении. Но в приведенном выше замечании вас интересует, "как tail узнает, где на диске найти конец файла?"Ответ прост: Хвост не знает. Процессы пользовательского уровня рассматривают файлы как непрерывные потоки, поэтому все, что
tail
можно знать, это смещение от начала файла. Но в файловой системе «inode» файла (запись каталога) связана со списком чисел, обозначающих физическое расположение блоков данных файла. Когда вы читаете из файла, ядро / драйвер устройства выясняет, какая часть вам нужна, определяет ее местоположение на диске и выбирает ее для вас.Для таких вещей у нас есть операционные системы: вам не нужно беспокоиться о том, где разбросаны блоки вашего файла.
источник
Если
head
илиtail
кажется, что он читает весь файл, вероятная причина состоит в том, что файл содержит мало или вообще не содержит символов новой строки . Я споткнулся об этом несколько месяцев назад с очень большим (гигабайтным) BLOB-объектом JSON, который был сериализован без пробелов, даже в виде строк.Если у вас GNU head / tail, вы можете использовать
-c N
для печати первых / последних N байтов вместо строк , но, к сожалению, это не функция POSIX.источник
Как вы можете видеть в строке исходного кода 525, вы можете увидеть комментарии для реализации.
источник