Как найти все символические ссылки, указывающие на любой файл/каталог внутри заданного каталога

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

В этом вопросе или в этом (например) вы получите решения о том, как искать символьные ссылки, указывающие на заданный каталог (назовем его /dir1), в то время как меня интересуют символические ссылки, которые могут указывать на любой файл/папку внутри /dir1.

Я хочу удалить этот каталог, но не уверен, что это безопасно, поскольку в другом каталоге (назовем его /dir2) у меня могут быть символьные ссылки, указывающие на внутренние части /dir1.

Кроме того, я мог создать эти символьные ссылки, используя абсолютные или относительные пути.
Единственное, что мне помогает, это то, что я знаю, что символьные ссылки, которые я хочу проверить, находятся на смонтированной файловой системе, на /dir2.

Вы можете найти все символические ссылки с помощью:

find / -type l 

вы можете выполнить это от имени root, чтобы получить доступ ко всем местам на диске.

Вы можете расширить их, используя readlink -f, чтобы получить полный путь к ссылке, и вы должны иметь возможность grep результатов по целевому каталогу, который вы рассматриваете для удаления:

find / -type l -exec readlink -f {} + | grep -F /dir2

Использование find / -type l -printf '%l\n' не сработает, так как вы получите относительные ссылки, такие как ../tmp/xyz, которые могут указывать на ваш целевой каталог, но не совпадают, потому что они не полностью расширены.

В моем случае принятый ответ не был полезен (потому что он не выводил источник ссылки). Вот что сработало для меня.

Я обошел это, используя два -exec условия:

find /home/ -type l -exec readlink -nf {} ';' -exec echo " <- {}" ';' | grep "/dir2"

С помощью zsh:

print -rC1 /dir2/**/*(ND@e['[[ $REPLY:P = /dir1(/*|) ]]'])

Разбито:

  • print -rC1: выводит свои аргументы rеальными в 1 Cтолбец. Здесь аргументами будут те, которые сгенерированы следующим шаблоном. Замените на ls -ld, чтобы получить больше информации о каждой символической ссылке¹
  • **/: любой уровень подкаталогов (рекурсивное сопоставление)
  • *: файл с любым именем (состоящим из любого количества символов, хотя * в zsh, как и в большинстве оболочек, также допускает несимвольные символы).
  • (...): квалификаторы шаблона для дальнейшего уточнения сопоставления по другим критериям, а не только по именам файлов
  • N: включает nullglob для этого одного шаблона (не вызовет ошибку, если совпадений нет, просто передаст пустой список в print, который ничего не выведет).
  • D: включает dotglob: также учитывать скрытые файлы.
  • @: ограничивает выбор файлами типа символьная ссылка.
  • e['code']: выбрать файлы, для которых code оценивается как истинное. Внутри code рассматриваемый файл хранится в $REPLY.
  • $REPLY:P: получает абсолютный и канонический (без символических ссылок) путь к файлу (аналогично тому, что делает стандартная функция realpath()).
  • [[ строка = шаблон ]] возвращает true, если строка соответствует шаблону (из ksh).
  • /dir1(/*|) как шаблон соответствует /dir1 самостоятельно или /dir1/, за которым идет что-то еще.

¹ с оговоркой, что если нет соответствующего файла, это перечислит текущий рабочий каталог. С ls было бы лучше удалить квалификатор N.

Мне нужна была первая ссылка, а не конечная:

find / -type l -exec readlink {} + | grep -F /dir2

В зависимости от вашей ситуации, вы можете удалить каталог, а затем удалить любые получившиеся недействительные символические ссылки с помощью следующего:

find -xtype l -delete

Тест xtype возвращает ‘l’, если символическая ссылка повреждена.

Ответ или решение

Чтобы найти все символические ссылки, указывающие на файлы или директории внутри заданной директории, вам понадобятся команды, доступные в UNIX-подобных операционных системах. Этот процесс может быть выполнен с помощью команды find, комбинируя ее с несколькими утилитами для обработки результатов. Ниже приводится подробное объяснение шагов, необходимых для достижения этой цели.

Шаг 1: Определите корневую директорию

Предположим, что ваша целевая директория называется /dir1, и вы хотите проверить, есть ли ссылки, указывающие на её содержимое (файлы и подкаталоги) из другой директории, например /dir2.

Шаг 2: Используйте команду find

Для поиска всех символических ссылок на файловой системе начиная с указанной директории, используйте следующую команду:

find /dir2 -type l

Эта команда находит все символические ссылки (-type l) в директории /dir2. Обратите внимание, что в этом случае команда ищет только в указанной директории и её подкаталогах.

Шаг 3: Разрешите символические ссылки и найдите цель

Вам необходимо расширить найденные символические ссылки, чтобы выяснить, на что они указывают. Для этого используйте readlink, чтобы извлечь информацию о целевых файлах ссылок:

find /dir2 -type l -exec readlink -f {} + | grep /dir1

Эта команда:

  • Ищет все символические ссылки в /dir2.
  • Использует -exec readlink -f {} для получения полного пути целевого файла для каждой ссылки.
  • Применяет grep /dir1, чтобы отфильтровать результаты и оставить только те, которые указывают на директорию или файл внутри /dir1.

Шаг 4: Обработка относительных ссылок

Важно помнить, что некоторые символические ссылки могут быть относительными. Если вам нужно также включить и относительные пути, вы можете использовать такую команду:

find /dir2 -type l -exec readlink {} + | grep -F /dir1

Это позволит вам увидеть только саму ссылку, а не полные пути, что может быть полезно в некоторых случаях.

Шаг 5: Использование Zsh для более сложного поиска

Если вы используете интерпретатор командной строки Zsh, вам доступны возможности сложного поиска через автоматическую подстановку:

print -rC1 /dir2/**/*(ND@e['[[ $REPLY:P = /dir1(/*|) ]]'])

Эта команда позволяет выполнить рекурсивный поиск символических ссылок и фильтровать их по паттерну. Параметры служат для настройки вывода так, чтобы отображались только ссылки, указывающие на файлы и директории внутри /dir1.

Шаг 6: Удаление недействительных ссылок

После удаления директории /dir1, если вам нужно очистить систему от недействительных символических ссылок, используйте следующую команду:

find /dir2 -xtype l -delete

Эта команда ищет («-xtype l») и удаляет все недействительные символические ссылки.

Заключение

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

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

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