Могу ли я определить количество подкаталогов в каталоге, используя `ls -l`?

8

При отображении каталогов с использованием ls -lих количество ссылок (второе поле в выходных данных) не менее двух: одна для имени каталога и одна для.

$ mkdir foo
$ ls -l
total 2
drwxr-xr-x  2 user   wheel  512  4 oct 14:02 foo

Безопасно ли всегда предполагать, что количество ссылок выше 2 соответствует количеству подкаталогов в этом каталоге ( ..ссылки)?

Евгений Ярмаш
источник

Ответы:

7

В Unix-системах обычно верно, что количество ссылок на каталог равно количеству подкаталогов плюс 2. Однако в некоторых случаях это не так:

  • Некоторые юниты допускают жесткие ссылки на каталоги. Тогда будет более 2 ссылок, которые не соответствуют подкаталогам.

  • Существуют файловые системы, в которых в каталогах нет записей для .и ... GNU найти руководство упоминает некоторые примеры в обсуждении его -noleafвариант (который отключает оптимизацию , которая предполагает , что .и ..существуют во всех каталогах): «CD-ROM или MS-DOS файловых систем или объем AFS точки монтирования»

Почти надежный способ подсчета количества подкаталогов (он может все еще не работать, если имя файла содержит символ новой строки)

$(($(LC_ALL=C ls -la /path/to/directory | grep '^d' | wc -l) - 2)

Более надежный способ использует оболочки */и оболочки .*/; как обычно, обработка случая, когда шаблон не совпадает, представляет собой небольшую боль (за исключением bash и zsh, где вы можете включить nullglobопцию).

Жиль "ТАК - перестань быть злым"
источник
2

Вот еще один способ подсчитать подкаталоги (не рекурсивно) в Bash:

(
shopt -s nullglob dotglob
printf '%s\000' */ | tr -dc '\0' | wc -c  # wc counts null bytes
)

Поскольку каждое имя файла заканчивается символом ASCII NUL, это должно работать правильно, даже если имя файла содержит символ новой строки.

матовый
источник
2

Вы можете попробовать с:

ls -l |grep ^d | wc -l
HandyGandy
источник
1

Я ничего не могу найти в документации, которая подтверждает, что количество ссылок всегда будет +2 на количество подкаталогов.

Но, чтобы найти правильную сумму, используйте:

find . -type d -mindepth 1  -maxdepth 1 | wc -l

Или, если вам нужно использовать ls -l, см. Другой ответ.

Стефан
источник
Я думаю, что вы имели в виду -type d, но: 1. это требует GNU find; 2. вам нужно вычесть 1 для начального каталога (или прохода -mindepth 1).
Жиль "ТАК - перестань быть злым"
0

Не используйте lsдля этого . Вот один способ, который работает со всеми именами файлов, даже с теми, которые содержат символы новой строки, потому что он печатает только символ новой строки вместо имени файла:

find . -mindepth 1 -maxdepth 1 -type d -printf '\n' | wc -l

Редактировать: текущая версия не приводит к каким-либо предупреждениям, потому что -mindepthи -maxdepthдолжно быть раньше -type(дерево каталогов сокращается перед проверкой каталогов, чтобы сэкономить время).

l0b0
источник