Как найти все символические ссылки в дереве каталогов?

255

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

Я пробовал эту команду:

find /var/www/ -type l

… И позже я обнаружил, что содержимое в них /var/wwwявляется символическими ссылками, поэтому я изменил команду на:

find -L /var/www/ -type l

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

Как мне получить это, чтобы проверить подкаталоги?

hafichuk
источник

Ответы:

301

Это будет рекурсивно проходить по /path/to/folderкаталогу и перечислять только символические ссылки:

ls -lR /path/to/folder | grep ^l

Если вы намерены также следовать символическим ссылкам, вам следует использовать findкоманду, но вы должны включить эту -Lопцию; на самом деле, findстраница руководства гласит:

   -L     Follow symbolic links.  When find examines or prints information
          about files, the information used shall be taken from the  prop‐
          erties  of  the file to which the link points, not from the link
          itself (unless it is a broken symbolic link or find is unable to
          examine  the file to which the link points).  Use of this option
          implies -noleaf.  If you later use the -P option,  -noleaf  will
          still  be  in  effect.   If -L is in effect and find discovers a
          symbolic link to a subdirectory during its search, the subdirec‐
          tory pointed to by the symbolic link will be searched.

          When the -L option is in effect, the -type predicate will always
          match against the type of the file that a symbolic  link  points
          to rather than the link itself (unless the symbolic link is bro‐
          ken).  Using -L causes the -lname and -ilname predicates  always
          to return false.

Тогда попробуйте это:

find -L /var/www/ -type l

Это, вероятно, сработает: я нашел на findстранице руководства этот ромб: если вы используете -typeопцию, вы должны изменить ее на -xtypeопцию:

          l      symbolic link; this is never true if the -L option or the
                 -follow option is in effect, unless the symbolic link  is
                 broken.  If you want to search for symbolic links when -L
                 is in effect, use -xtype.

Затем:

find -L /var/www/ -xtype l
ztank1013
источник
1
Спасибо, это, вероятно, сработает, однако я только что заметил, что содержимое / var / www / уже является символическими ссылками, и похоже, что оно не попадает в эти каталоги.
хафичук
4
@hafichuk см окончательное редактирование в моем ответе ( find -L /var/www/ -xtype l). Использование -xtypeвместо -typeдолжно сделать трюк в вашей находке. Удачи!
ztank1013
3
Сделайте это, ls -laR /path/to/folder | grep ^lесли вы также хотите обрабатывать «скрытые» папки с точками ...
wimvds
2
Спасибо! Но это показывает только название ссылок, но не их местоположение.
Костанос
8
в Mac OSX (10.9), -xtypeнедоступно. find . -type lкажется, проверяет рекурсивно.
Амерткара
227

Одна команда, без труб

find . -type l -ls

Пояснение: find из текущего каталога и .далее все ссылки на -type lчернила и перечислите -lsих подробно. Легко и просто...

В продолжение этого ответа приведем еще пару findкоманд, связанных с символьными ссылками :

Найти символические ссылки на конкретную цель

find . -lname link_target

Обратите внимание, что link_targetэто шаблон, который может содержать символы подстановки.

Найти неработающие символические ссылки

find -L . -type l -ls

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

Найти и заменить неработающие символические ссылки

find -L . -type l -delete -exec ln -s new_target {} \;

Больше найти примеры

Дополнительные findпримеры можно найти здесь: https://hamwaves.com/find/

Серж Строобандт
источник
7
Если вы хотите быть более кратким, стоит упомянуть, что большинство версий findимеют -lsопцию. Так find . -type l -lsдолжно быть эквивалент выше.
Братчли
7
Это улучшает принятый ответ, потому что он также сообщает вам, где находятся символические ссылки в дереве каталогов, что особенно важно при работе с таким сложным и глубоким деревом, которое может иметь символические ссылки.
Джесси Кроссен
2
Лучше, чтобы вопрос был принят как лучший ответ.
Lord_Dracon
3
Этот ответ гораздо полезнее принятого. Кроме того , если вы хотите , чтобы найти ссылки которые указывают на файлы в каком - нибудь каталоге: find -lname '*/dir/*' -printf '%P -> %l\n'. Стоит отметить, что link_target - это шаблон.
x-yuri
1
Это мой тип ответа. Легко и просто. Спасибо.
Правда,
11

find уже выглядит рекурсивно по умолчанию:

[15:21:53 ~]$ mkdir foo
[15:22:28 ~]$ cd foo
[15:22:31 ~/foo]$ mkdir bar
[15:22:35 ~/foo]$ cd bar
[15:22:36 ~/foo/bar]$ ln -s ../foo abc
[15:22:40 ~/foo/bar]$ cd ..
[15:22:47 ~/foo]$ ln -s foo abc
[15:22:52 ~/foo]$ find ./ -type l
.//abc
.//bar/abc
[15:22:57 ~/foo]$ 
Jman
источник
Вероятно, это одна из тех ошибок, все файлы в / var / www являются символическими ссылками. findРекурсирует ли это по умолчанию? Наверное, нет;)
хафичук
Я, наверное, чтобы избежать зацикливания.
jman
Я обновил, чтобы использовать -Lфлаг для поиска без удачи - какие-либо догадки?
хафичук
Идеальное решение, и оно показывает расположение ссылок. Спасибо!
Костанос
8

Чтобы увидеть только символические ссылки, вы можете использовать

find -L /path/to/dir/ -xtype l 

в то время как если вы хотите увидеть также, какие файлы они целевые, просто добавьте ls

find -L /path/to/dir/ -xtype l -exec ls -al {} \;
MariusPontmercy
источник
6

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

find ./ -type l -print0 | xargs -0 ls -plah

вывод выглядит примерно так:

lrwxrwxrwx 1 apache develop 99 Dec  5 12:49 ./dir/dir2/symlink1 -> /dir3/symlinkTarget
lrwxrwxrwx 1 apache develop 81 Jan 10 14:02 ./dir1/dir2/dir4/symlink2 -> /dir5/whatever/symlink2Target
etc...
оборота Силиконрокстар
источник
0

Что я делаю, так это создаю скрипт в каталоге bin, похожий на псевдоним. Например, у меня есть скрипт с именем lsd ls -l | grep ^ d

Вы могли бы сделать один lsl ls -lR | grep ^ l

Просто chmod их + х, и вы готовы идти.

Алекс М
источник