Как найти сломанные символические ссылки

Есть ли способ найти все символические ссылки, которые не указывают ничего?

find ./-type l

предоставит мне все символические ссылки, но не делает различий между ссылками, которые идут куда-то, и ссылками, которые этого не делают.

Сейчас я делаю:

find ./-type l -exec file {} \; | grep broken

Но мне интересно, какие альтернативные решения существуют.

225 голосов | спросил gabe. 15 MarpmThu, 15 Mar 2012 20:29:44 +04002012-03-15T20:29:44+04:0008 2012, 20:29:44

9 ответов


286

Я настоятельно рекомендую не использовать find -L для задачи (см. ниже пояснение). Вот несколько способов сделать это:

  • Если вы хотите использовать метод «pure find», он должен выглядеть примерно так:

    find. -xtype l
    

    ( xtype ) - это тест, выполняемый по разыменованной ссылке). Однако это может быть недоступно во всех версиях find. Но есть и другие варианты:

  • Вы также можете выполнить exec test -e из команды find:

    find. Тип l! -exec test -e {} \; -Распечатать
    
  • Даже некоторый трюк grep может быть лучше (т. е. безопаснее ), чем find -L, но не совсем такой, как представлен в вопросе (который загорается во всех выходных строках, включая имена файлов):

    find. -type l -exec sh -c 'file -b "$ 1" | grep -q ^ broken 'sh {} \; -Распечатать
    

Тройка find -L цитируется соло из commandlinefu выглядит красиво и взломанно, но у него есть одна очень сильная опасная ошибка : соблюдаются все символические ссылки. Рассмотрим каталог с содержимым, представленным ниже:

$ ls -l
всего 0
lrwxrwxrwx 1 пользователя michal 6 мая 15 08:12 link_1 -> nonexistent1
lrwxrwxrwx 1 пользователя michal 6 мая 15 08:13 link_2 -> nonexistent2
lrwxrwxrwx 1 пользователя michal 6 мая 15 08:13 link_3 -> nonexistent3
lrwxrwxrwx 1 пользователя michal 6 мая 15 08:13 link_4 -> nonexistent4
lrwxrwxrwx 1 пользователя michal 11 мая 15 08:20 link_out -> /USR /доли /

Если вы запустите find -L. -type l, в этом каталоге будут также выполняться все /usr /share / (и это может занять очень много времени) 1 . Для команды find, которая «невосприимчива к исходящим ссылкам», не используйте -L .


1 Это может показаться незначительным неудобством (команда «просто» займет много времени, чтобы пройти все /usr /share), но может иметь более серьезные последствия. Например, рассмотрите среды chroot: они могут существовать в какой-то подкаталоге основной файловой системы и содержать символические ссылки в абсолютные местоположения. Эти ссылки могут быть нарушены для «внешней» системы, потому что они указывают только на правильные места, как только вы вошли в chroot. Я также помню, что некоторые загрузчики использовали символические ссылки в /boot, которые имели смысл только в начальной фазе загрузки, когда загрузочный раздел был установлен как /.

Итак, если вы используете команду find -L для поиска, а затем удаления сломанных символических ссылок из какого-то безобидного вида каталога, вы можете даже сломать свою систему ...

ответил rozcietrzewiacz 15 Mayam12 2012, 11:01:37
34

Команда symlinks из http: //www.ibiblio.org/pub/Linux/utils/file/symlinks-1.4.tar.gz можно использовать для идентификации символических ссылок с различными характеристиками. Например:

$ rm a
$ ln -s a b
$ символических ссылок.
свисание: /tmp /b ->
ответил Sam Morris 15 MarpmThu, 15 Mar 2012 21:38:01 +04002012-03-15T21:38:01+04:0009 2012, 21:38:01
23

Как уже прокомментировал rozcietrzewiacz, find -L может иметь неожиданные последствия расширения поиска в символических каталогах, поэтому это не оптимальный подход. Что еще никто не упомянул, что

find /path /to /search -xtype l

является более сжатой и логически идентичной командой

find /path /to /search -type l -xtype l

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

find /path /to /search -type l -exec test! -e {} \; -print

Подробнее см. этот вопрос или ynform.org . Конечно, окончательным источником всего этого является findutils documentaton .

ответил pooryorick 29 thEurope/Moscowp30Europe/Moscow09bEurope/MoscowSat, 29 Sep 2012 18:02:59 +0400 2012, 18:02:59
6

Я полагаю, что добавление флага -L к вашей команде позволит вам избавиться от grep:

$ find -L. Тип l

http://www.commandlinefu.com/commands/view/8260 /найти разбитую-символьные ссылки

от человека:

-L Вывести информацию о файле и тип файла (см. stat (2))
         для каждой символической ссылки должны быть ссылки на файл, на который ссылается
         ссылка, а не сама ссылка. Если ссылочный файл не существует,
         информация и тип файла будут для самой ссылки.
ответил kwarrick 15 MarpmThu, 15 Mar 2012 20:52:49 +04002012-03-15T20:52:49+04:0008 2012, 20:52:49
5

Если вам нужно другое поведение, если ссылка сломана или циклическая, вы также можете использовать% Y с помощью find:

$ touch a
$ ln -s a b # ссылка на существующую цель
Ссылка $ ln -s c d # на несуществующую цель
$ ln -s e e # ссылка на себя
$ find. -тип l -exec test! -e {} \; -printf '% Y% p \ n' \
   | при чтении типа ссылки; делать
         case "$ type" в
         N) эхо "сделать что-то со сломанной ссылкой $ link" ;;
         L) echo «делать что-то с циклической ссылкой $ link» ;;
         ESAC
      сделанный
сделать что-то со сломанной ссылкой ./d
делать что-то с циклической ссылкой ./e

Этот пример скопирован из этого сообщения (сайт удален) .

Ссылка

ответил andy 26 WedEurope/Moscow2012-12-26T10:56:03+04:00Europe/Moscow12bEurope/MoscowWed, 26 Dec 2012 10:56:03 +0400 2012, 10:56:03
0

найдите -L. -type l | xargs symlinks предоставит вам информацию о том, существует ли ссылка или нет на основе каждого файла.

ответил Alex 30 AMpTue, 30 Apr 2013 10:37:55 +040037Tuesday 2013, 10:37:55
0

Это будет печатать имена сломанных символических ссылок в текущем каталоге.

для l в $ (find -type l); do cd $ (dirname $ l); если [ ! -e "$ (readlink $ (basename $ l))"]; затем echo $ l; Fi; cd -> /DEV /нуль; сделанный

Работает в Bash. Не знаю о других снарядах.

ответил conradkdotcom 24 +04002014-10-24T18:33:36+04:00312014bEurope/MoscowFri, 24 Oct 2014 18:33:36 +0400 2014, 18:33:36
0

Я использую это для своего случая, и он работает очень хорошо, поскольку я знаю, что каталог ищет сломанные символические ссылки:

find -L $ path -maxdepth 1-type l

и моя папка содержит ссылку на /usr /share, но она не пересекает ее. Перекрестные ссылки на устройства и те, которые действительны для chroots и т. Д., Все еще являются ловушкой, но для моего использования это достаточно.

ответил Iskren 8 PM00000050000003631 2015, 17:01:36
0

Простой бездумный ответ, который является вариантом версии OP. Иногда вам просто нужно что-то легко набрать или запомнить:

find. | Файл xargs | grep -i "сломанная символическая ссылка"
ответил trinth 18 PMpWed, 18 Apr 2018 21:13:51 +030013Wednesday 2018, 21:13:51

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132