Найдите элементы по имени и выведите, являются ли они файлами или каталогами.

Вопрос или проблема

Рассмотрим следующий пример:

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:

  1. Поиск по имени: find . -name <имя> — эта команда позволяет находить все файлы и директории с определённым именем, начиная с текущего каталога.

  2. Использование -exec: С помощью опции -exec можно выполнять команду для каждого из найденных файлов/директорий. Однако, следует внимательно относиться к правильному использованию скобок и других символов (например, {} и +), чего часто бывает непросто достичь без ошибок.

  3. Различие между файлами и директориями: В выводе команды ls, если элемент является директорией, его права доступа начинаются с d (например, drwxr-xr-x), в то время как у файлов — с - (например, -rw-r--r--).

  4. Параметр -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, для самих файлов или директорий, без раскрытия содержимого директорий.

Применение

Теперь давайте рассмотрим, как применять эти знания на практике, расширив сценарий использования:

  1. Автоматизация работы с файлами: Если вы разрабатываете скрипты для автоматизации, то понимание работы с командами поиска файлов критично важно. Например, можно использовать найденные файлы для их последующего резервного копирования, удаления старых версий или проверки их доступа.

  2. Управление большим количеством данных: В больших системах и на серверах часто возникает необходимость провести аудит: выяснить структуру файлов, проверить права доступа, отыскать лишние или ненужные данные. Это особенно актуально для системных администраторов при оптимизации использования дискового пространства.

  3. Защита и безопасность данных: Одной из ключевых задач может быть определение неправильных настроек доступа к файлам и директориям, что может приводить к потенциальным проблемам с безопасностью. Проверка и анализ через команды find и ls помогают выявлять уязвимости.

  4. Отладка и анализ процессов: В процессе работы над проектами разработчики могут использовать такие команды для отладки, чтобы точно знать, какие файлы создаются, куда записывается выход. Удобно также смотреть иерархию файлов для видео и разработки, где структурированные данные критичны.

Таким образом, понимание и умение использовать команды find и ls являются важными элементами в арсенале ИТ-специалиста. Этот навык позволяет не только эффективно и безопасно управлять файловой системой, но и автоматизировать многие рутинные задачи, улучшая производительность труда и минимизируя ошибки, связанные с человеческим фактором.

Оцените материал
Добавить комментарий

Капча загружается...