Вопрос или проблема
Я создал символьные ссылки на большое количество файлов журналов. Синтаксис файлов журналов — yyyymmdd.log.gz
.
Чтобы упростить задачу, я использую простую последовательность без парсинга с помощью date
:
for dd in $(seq -w 20150101 20151231) ; do
ln -s $origin/$dd.log.gz $target/$dd.log.gz
done
Как мне избавиться от всех сломанных символьных ссылок, которые я только что создал, одним махом?
Эта простая однострочная команда выполняет задачу довольно быстро. Она требует GNU Findutils:
find . -xtype l -delete
Немного объяснений:
-xtype l
проверяет на наличие сломанных ссылок (это противоположность -type
)
-delete
удаляет файлы непосредственно, без необходимости дальнейшего использования xargs
или -exec
ПРИМЕЧАНИЕ: -xtype l означает -xtype строчная L (как в link) 😉
find -L /path -type l -exec rm -i {} \;
С помощью -L
команда find
пытается следовать по символьным ссылкам, чтобы оценить тест -type
. Если она может следовать по ссылке, значит, ссылка не сломана, и тест -type l
будет ложным (так как он оценивается по объекту, на который ссылается ссылка). Если она не может следовать по ссылке, то ссылка сломана, и тест -type l
будет истинным.
Если тест -type l
проходит успешно, тогда команда -exec rm {} \;
удаляет сломанную ссылку.
Предложение использовать -xtype l
является GNU-признаком, в первую очередь для пользователей Linux, и не будет работать на ненадежных UNIX-системах, таких как Solaris, FreeBSD и т. д.
С помощью zsh
(вы на самом деле используете синтаксис zsh
в своем коде; в bash
вам нужно будет заключить переменные в кавычки):
rm -- $target/*(-@)
Или:
rm -- $target/<20150101-20151231>.log.gz(-@)
*(@)
соответствует файлам типа символьная ссылка. *(-@)
— это те, которые все еще являются типом символьная ссылка после разрешения символьной ссылки (то есть те, для которых цель символьной ссылки не может быть разрешена). Это эквивалентно -xtype l
в GNU find
.
В zsh
и с GNU ln
вы бы написали свой цикл так:
ln -srt $target -- $origin/<20150101-20151231>.log.gz
Что также сработает, даже если $origin
содержит относительный путь (и создает относительные символьные ссылки, что снижает риск поломки символьных ссылок, если некоторые компоненты пути origin (те, которые общие с target) будут переименованы в будущем).
Ответ Роба Каррента определенно полезен и работает.
Еще один пример можно найти через man find
на macOS для удаления всех сломанных символьных ссылок в заданном каталоге.
Допустим, у вас есть каталог /usr/ports/packages
, содержащий сломанные символьные ссылки на другие файлы или каталоги, которые были перемещены или удалены, следующая команда удалит все символьные ссылки, для которых ранее связанный файл больше не существует.
EXAMPLES
Следующие примеры представлены так, как они даны оболочке:
...
find -L /usr/ports/packages -type l -exec rm -- {} +
Удаляет все сломанные символьные ссылки в /usr/ports/packages.
...
BSD 28 сентября 2011 BSD
Опция -L
(в соответствии с man find
) заставляет информацию о файле и тип файла, возвращаемые для каждой символьной ссылки, быть таковыми, как для файла, на который ссылается ссылка, а не самой ссылки. Если же упомянутый файл не существует, информация о файле и тип будут для самой ссылки.
Опция -type l
ограничивает найденные файлы только теми, которые являются символьными ссылками.
Что следует после оператора -exec
, это команда для выполнения для соответствующих файлов.
Оператор --
заставляет rm, который использует getopt(3) для разбора своих аргументов, прекратить обработку опций флагов после этого.
Как объясняет man find
, синтаксис exec utility [argument ...] {} +
имеет тот же эффект, что и -exec
, за исключением того, что “{}” заменяется на максимальное количество имен файлов для каждого вызова утилиты. Это поведение похоже на поведение команды xargs(1).
Надеюсь, это поможет.
Если все сломанные ссылки были созданы из-за ошибки команды в определенный момент времени, то следующий вариант сработает хорошо.
ls -lrt | grep "Sep 17 15:06" | awk '{print $9}' | xargs \rm
Учитывая детали вопроса, возможно, вам стоит использовать:
find . -maxdepth 1 -xtype l -delete
Ответ или решение
Удаление сломанных символических ссылок в системах UNIX/Linux может быть выполнено несколькими способами. Ниже я описываю наиболее эффективные методы, которые позволят вам быстро и просто избавиться от этих ссылок.
Метод 1: Использование команды find
Команда find
— это мощный инструмент, который позволяет находить и удалять файлы в иерархии каталогов. Чтобы удалить все сломанные символические ссылки, вы можете использовать следующую команду:
find . -xtype l -delete
Объяснение компонентов команды:
find
— команда для поиска файлов и каталогов..
— указывает на текущий каталог; вы можете заменить его на путь к интересующему каталогу.-xtype l
— находит только сломанные символические ссылки.-delete
— удаляет найденные файлы без необходимости дополнительных действий.
Метод 2: Альтернативный метод для macOS и FreeBSD
Если вы используете macOS или другую систему, которая не поддерживает -xtype
, можете воспользоваться следующим подходом:
find -L /path/to/directory -type l -exec rm -- {} +
Краткая информация о ключевых параметрах:
-L
— заставляетfind
следовать символическим ссылкам. Если целевой файл недоступен,-type l
будет истинным для сломанной ссылки.-type l
— ограничивает поиск только символическими ссылками.-exec rm -- {} +
— выполняет команду удаления для всех найденных символических ссылок.
Метод 3: Команда rm в оболочке zsh
Если вы используете оболочку zsh
, вы можете использовать следующий синтаксис:
rm -- $target/*(-@)
Здесь *($@)
находит все символьные ссылки, а *(-@)
— только те, которые не имеют действительного целевого файла.
Примечания
-
Системные ограничения: Обратите внимание, что подходы, зависящие от использования
-xtype
, в основном ограничены системами на основе GNU. На других системах, таких как Solaris и FreeBSD, имеет смысл использовать-L
с-type l
. -
Безопасность удаления: Если вы хотите убедиться, что удаление выполняется корректно, добавьте ключ
-i
к командеrm
, чтобы запрашивать подтверждение перед удалением каждой ссылки:
find . -xtype l -exec rm -i {} \;
- Ограничение глубины поиска: Если вы хотите удалить сломанные ссылки только в текущем каталоге, используйте
-maxdepth 1
:
find . -maxdepth 1 -xtype l -delete
Заключение
Использование команды find
со специальными опциями является самым эффективным способом удаления сломанных символических ссылок в Unix-подобных системах. Этот метод не только быстр, но и позволяет избегать случайных ошибок при удалении. Важно помнить о типе системы, чтобы выбрать правильный командный синтаксис.
Следуя предложенным методам и рекомендациям, вы сможете эффективно управлять своими символическими ссылками и поддерживать порядок в файловой системе.