Вопрос или проблема
Рассмотрим следующий пример:
mkdir /tmp/test2 && cd /tmp/test2
mkdir -p aa/{tmp,src}
mkdir -p bb/aa/{tmp,src}
mkdir -p {dd,ee}/bb
touch {dd,ee}/bb/aa
tree | awk '{print "# " $0}'
# .
# ├── aa
# │ ├── src
# │ └── tmp
# ├── bb
# │ └── aa
# │ ├── src
# │ └── tmp
# ├── cc
# │ └── aa
# │ ├── src
# │ └── tmp
# ├── dd
# │ └── bb
# │ └── aa
# └── ee
# └── bb
# └── aa
#
# 16 директорий, 2 файла
Итак, я хочу найти все элементы с именем aa
и вывести их в том же формате, что и ls -la
, чтобы я мог увидеть, являются ли они файлами или директориями.
Если я выполню типичную команду find
с exec
для ls -a
– тогда сами директории не выводятся как элементы, но вместо этого выдается их содержимое:
$ find . -name aa -exec ls -la {} \;
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 12:00 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 11:59 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
total 0
drwxr-xr-x 1 user None 0 Feb 19 11:59 .
drwxr-xr-x 1 user None 0 Feb 19 11:59 ..
drwxr-xr-x 1 user None 0 Feb 19 11:59 src
drwxr-xr-x 1 user None 0 Feb 19 11:59 tmp
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./dd/bb/aa
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./ee/bb/aa
Если я вместо этого использую ls -lad {}/
, чтобы явно выводить только сами узлы директорий, тогда узлы файлов вообще не выводятся, но я получаю ошибку “Not a directory”:
$ find . -name aa -exec ls -lad {}/ \;
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./bb/aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./cc/aa/
ls: cannot access './dd/bb/aa/': Not a directory
ls: cannot access './ee/bb/aa/': Not a directory
Если я попробую какой-то условный оператор bash
непосредственно в командной строке, он не сработает:
# test
$ [ -d aa ] && echo dir || echo file
dir
$ find . -name aa -exec [ -d {} ] && ls -lad {}/ || ls -la {} \;
find: missing argument to `-exec'
ls: cannot access '{}': No such file or directory
ls: cannot access ';': No such file or directory
Итак, как я могу использовать find . -name aa
, чтобы в конечном итоге получить следующий вывод:
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./bb/aa/
drwxr-xr-x 1 user None 0 Feb 19 11:59 ./cc/aa/
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./dd/bb/aa
-rw-r--r-- 1 user None 0 Feb 19 12:00 ./ee/bb/aa
Вы были почти правы с этим:
find . -name aa -exec ls -lad {}/ \;
Вам нужна опция -d
, но без завершающего /
.
Вы также можете опустить опцию -a
, которая не нужна для вашего случая.
Таким образом, это работает нормально:
find . -name aa -exec ls -ld {} \;
Однако, с \;
команда ls
вызывается для каждого элемента. Вам следует использовать +
вместо этого, чтобы ls
вызывалась с максимальным допустимым количеством аргументов:
find . -name aa -exec ls -ld {} +
Добавьте -p
, чтобы получить завершающий /
в вашем выводе (спасибо @Stéphane Chazelas), но это не обязательно, так как вы можете отделить файлы от директорий по ведущему d
в информации о разрешениях.
Также, вы можете использовать опцию -ls
команды find
, но это даст немного другой вывод. Обратите внимание, что это распространенная, но нестандартная опция для find
.
find . -name aa -ls
.
Ответ или решение
Вопрос, касающийся поиска и вывода элементов с заданным именем (например, "aa"), с указанием, являются ли они файлами или директориями, может вызвать некоторые сложности, особенно если рассматривать вопросы многоуровневой файловой структуры и особенностей работы команд командной строки Linux. Рассмотрим эту задачу подробнее, начав с теоретической части, приведем примеры и наконец, объясним, как применить полученные знания на практике.
Теория
В операционных системах на базе Unix/Linux одна из часто используемых задач — это поиск и манипуляция файлами и директориями. Команда find
обеспечивает мощные возможности для таких задач.
Ключевые моменты при работе с командой find
:
-
Поиск по имени:
find . -name <имя>
— эта команда позволяет находить все файлы и директории с определённым именем, начиная с текущего каталога. -
Использование
-exec
: С помощью опции-exec
можно выполнять команду для каждого из найденных файлов/директорий. Однако, следует внимательно относиться к правильному использованию скобок и других символов (например,{}
и+
), чего часто бывает непросто достичь без ошибок. -
Различие между файлами и директориями: В выводе команды
ls
, если элемент является директорией, его права доступа начинаются сd
(например,drwxr-xr-x
), в то время как у файлов — с-
(например,-rw-r--r--
). -
Параметр
-d
вls
: Этот параметр используется для того, чтобыls
отображал информацию только о самих директориях, а не о их содержимом.
Пример
Рассмотрим пример со структурой, уже упомянутой в вопросе:
mkdir /tmp/test2 && cd /tmp/test2
mkdir -p aa/{tmp,src} bb/aa/{tmp,src} {dd,ee}/bb
touch {dd,ee}/bb/aa
После выполнения этих команд, мы получим файловую систему с несколькими директориями и файлами, которые имеют одинаковое имя "aa". Следующая команда поможет нам отобразить только сами узлы (файлы или директории) с именем "aa":
find . -name aa -exec ls -ld {} +
Здесь пробегаем по каждому из элементов, который находит команда find
, и применяем к ним ls -ld
, выводя информацию, схожую с ls -la
, для самих файлов или директорий, без раскрытия содержимого директорий.
Применение
Теперь давайте рассмотрим, как применять эти знания на практике, расширив сценарий использования:
-
Автоматизация работы с файлами: Если вы разрабатываете скрипты для автоматизации, то понимание работы с командами поиска файлов критично важно. Например, можно использовать найденные файлы для их последующего резервного копирования, удаления старых версий или проверки их доступа.
-
Управление большим количеством данных: В больших системах и на серверах часто возникает необходимость провести аудит: выяснить структуру файлов, проверить права доступа, отыскать лишние или ненужные данные. Это особенно актуально для системных администраторов при оптимизации использования дискового пространства.
-
Защита и безопасность данных: Одной из ключевых задач может быть определение неправильных настроек доступа к файлам и директориям, что может приводить к потенциальным проблемам с безопасностью. Проверка и анализ через команды
find
иls
помогают выявлять уязвимости. -
Отладка и анализ процессов: В процессе работы над проектами разработчики могут использовать такие команды для отладки, чтобы точно знать, какие файлы создаются, куда записывается выход. Удобно также смотреть иерархию файлов для видео и разработки, где структурированные данные критичны.
Таким образом, понимание и умение использовать команды find
и ls
являются важными элементами в арсенале ИТ-специалиста. Этот навык позволяет не только эффективно и безопасно управлять файловой системой, но и автоматизировать многие рутинные задачи, улучшая производительность труда и минимизируя ошибки, связанные с человеческим фактором.