Что делает & ldquo; total = n & rdquo; в выводе & ldquo; ls -l & rdquo; показывают? [dубликат]

Видимо, я не могу рассчитывать. Я думаю, что в /media

есть три файла

$ tree /media /media ├── foo ├── onex └── zanna 3 directories, 0 files

Однако ls -l находит 12.

$ ls -l /media total 12 drwxr-xr-x 2 root root 4096 Jul 31 20:57 foo drwxrwxr-x 2 root root 4096 Jun 26 06:36 onex drwxr-x---+ 2 root root 4096 Aug 7 21:17 zanna

И если я сделаю ls -la, я получаю только . и .. в дополнение к вышесказанному, но счет total 20

Какое объяснение?

24
задан 10 October 2017 в 21:11

4 ответа

Вы видите, что 12 - это не количество файлов, а количество потребляемых блоков.

Из info coreutils 'ls invocation':

For each directory that is listed, preface the files with a line `total BLOCKS', where BLOCKS is the total disk allocation for all files in that directory. The block size currently defaults to 1024 bytes, but this can be overridden (*note Block size::). The BLOCKS computed counts each hard link separately; this is arguably a deficiency.

Общее количество идет от 12 - 20, когда вы используете ls -la вместо ls -l, потому что вы считаете два дополнительных каталога: . и ... Вы используете четыре дисковых блока для каждого (пустого) каталога, поэтому ваше общее количество идет от 3 & times; От 4 до 5 раз; 4. (По всей вероятности, вы используете один блок диска из 4096 байт для каждой директории, как показывает страница info, утилита не проверяет формат диска, но предполагает размер блока 1024, если не указано иное. )

Если вы хотите просто получить количество файлов, вы можете попробовать что-то вроде

ls | wc -l
32
ответ дан 17 July 2018 в 23:19

Вы видите, что 12 - это не количество файлов, а количество потребляемых блоков.

Из info coreutils 'ls invocation':

For each directory that is listed, preface the files with a line `total BLOCKS', where BLOCKS is the total disk allocation for all files in that directory. The block size currently defaults to 1024 bytes, but this can be overridden (*note Block size::). The BLOCKS computed counts each hard link separately; this is arguably a deficiency.

Общее количество идет от 12 - 20, когда вы используете ls -la вместо ls -l, потому что вы считаете два дополнительных каталога: . и ... Вы используете четыре дисковых блока для каждого (пустого) каталога, поэтому ваше общее количество идет от 3 & times; От 4 до 5 раз; 4. (По всей вероятности, вы используете один блок диска из 4096 байт для каждой директории, как показывает страница info, утилита не проверяет формат диска, но предполагает размер блока 1024, если не указано иное. )

Если вы хотите просто получить количество файлов, вы можете попробовать что-то вроде

ls | wc -l
32
ответ дан 24 July 2018 в 13:50

user4556274 уже ответил, почему. Мой ответ служит только для предоставления дополнительной информации о том, как правильно подсчитывать файлы.

В сообществе Unix общий консенсус заключается в том, что синтаксический анализ вывода ls - очень плохая идея, поскольку имена файлов могут содержать контроль символов или скрытых символов. Например, из-за символа новой строки в имени файла мы ls | wc -l сообщают, что на выходе ls (что у него есть) есть 5 строк, но на самом деле в каталоге есть только 4 файла.

$> touch FILE$'\n'NAME $> ls file1.txt file2.txt file3.txt FILE?NAME $> ls | wc -l 5

Команда find, которая обычно используется для работы с парсингом имен файлов, может помочь нам здесь, напечатав номер inode. Будь то каталог или файл, он имеет только один уникальный номер inode. Таким образом, используя -printf "%i\n" и исключая . через -not -name ".", мы можем иметь точный подсчет файлов. (Обратите внимание на использование -maxdepth 1, чтобы предотвратить рекурсивное спуск в подкаталоги)

$> find -maxdepth 1 -not -name "." -print ./file2.txt ./file1.txt ./FILE?NAME ./file3.txt $> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l 4

То же самое можно использовать с stat для подсчета номеров индексных номеров в строке:

$> LC_ALL=C stat ./* --printf "%i\n" | wc -l 4

Альтернативный подход заключается в использовании шаблона. (Обратите внимание, что в этом тесте используется другой каталог для проверки того, сходит ли этот подход в подкаталоги, чего нет - 16 - это проверенное количество элементов в моем ~/bin)

$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1 16

Python также может работать с проблемными именами файлов путем печати длины списка с учетом моей функции os.listdir() (которая не является рекурсивной и будет перечислять только элементы в каталоге, указанном как аргумент).

$> python -c "import os ; print os.listdir('.')" ['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt'] $> python -c "import os ; print(len(os.listdir('.')))" 4
18
ответ дан 17 July 2018 в 23:19

user4556274 уже ответил, почему. Мой ответ служит только для предоставления дополнительной информации о том, как правильно подсчитывать файлы.

В сообществе Unix общий консенсус заключается в том, что синтаксический анализ вывода ls - очень плохая идея, поскольку имена файлов могут содержать контроль символов или скрытых символов. Например, из-за символа новой строки в имени файла мы ls | wc -l сообщают, что на выходе ls (что у него есть) есть 5 строк, но на самом деле в каталоге есть только 4 файла.

$> touch FILE$'\n'NAME $> ls file1.txt file2.txt file3.txt FILE?NAME $> ls | wc -l 5

Команда find, которая обычно используется для работы с парсингом имен файлов, может помочь нам здесь, напечатав номер inode. Будь то каталог или файл, он имеет только один уникальный номер inode. Таким образом, используя -printf "%i\n" и исключая . через -not -name ".", мы можем иметь точный подсчет файлов. (Обратите внимание на использование -maxdepth 1, чтобы предотвратить рекурсивное спуск в подкаталоги)

$> find -maxdepth 1 -not -name "." -print ./file2.txt ./file1.txt ./FILE?NAME ./file3.txt $> find -maxdepth 1 -not -name "." -printf "%i\n" | wc -l 4

То же самое можно использовать с stat для подсчета номеров индексных номеров в строке:

$> LC_ALL=C stat ./* --printf "%i\n" | wc -l 4

Альтернативный подход заключается в использовании шаблона. (Обратите внимание, что в этом тесте используется другой каталог для проверки того, сходит ли этот подход в подкаталоги, чего нет - 16 - это проверенное количество элементов в моем ~/bin)

$> count=0; for item in ~/bin/* ; do count=$(($count+1)) ; echo $count ; done | tail -n 1 16

Python также может работать с проблемными именами файлов путем печати длины списка с учетом моей функции os.listdir() (которая не является рекурсивной и будет перечислять только элементы в каталоге, указанном как аргумент).

$> python -c "import os ; print os.listdir('.')" ['file2.txt', 'file1.txt', 'FILE\nNAME', 'file3.txt'] $> python -c "import os ; print(len(os.listdir('.')))" 4
18
ответ дан 24 July 2018 в 13:50
  • 1
    В bash другой вариант заключается в использовании массива, например. items=( dir/* ); echo ${#items[@]} (добавление shopt -s dotglob для включения скрытых файлов). – steeldriver 11 August 2016 в 07:01
  • 2
    Печать номеров индексных номеров упрощает фильтрацию жестких ссылок, если необходимо, с помощью find | sort -u | wc -l. – Peter Cordes 11 August 2016 в 07:06
  • 3
    @steeldriver: Я думаю, что метод bash-array вряд ли будет быстрее. Если вы хотите, чтобы он был рекурсивным, вам нужно использовать items=( dir/** ) (с shopt -s globstar), но bash не использует лишние метаданные из readdir, поэтому он определяет каждую запись в каталоге, чтобы узнать, является ли это самой папкой. Многие файловые системы сохраняют тип файла в записи каталога, поэтому readdir может возвращать его без доступа к inodes. (например, в последней версии XFS, отличной от используемой по умолчанию, и я думаю, что ext4 имеет ее дольше.) Если вы найдете strace, вы увидите гораздо меньше stat системных вызовов, чем stracing bash. – Peter Cordes 11 August 2016 в 07:11
  • 4
    Почему бы просто не использовать print(len(os.listdir('.')))? Меньшее количество символов для ввода, а также избегает доступа к двунаправленным атрибутам. – edwinksl 11 August 2016 в 08:05
  • 5
    @edwinksl отредактировал thx – Sergiy Kolodyazhnyy 11 August 2016 в 08:46

Другие вопросы по тегам:

Похожие вопросы: