- How to find all symbolic links pointing to any file/directory inside a given directory
- 4 Answers 4
- Not the answer you’re looking for? Browse other questions tagged symlink or ask your own question.
- Linked
- Related
- Hot Network Questions
- Subscribe to RSS
- How can I find broken symlinks
- 11 Answers 11
- Find out symbolic link target via command line
- 9 Answers 9
- How to list all symbolic links in a directory
- 9 Answers 9
- Поиск и удаление битых символьных ссылок в Linux
- Символьные ссылки
- Создание символьных ссылок
- Битые символьные ссылки
- Поиск битых символьных ссылок (команда find)
- Анализ битых символьных ссылок
- Удаление битых символьных ссылок
- Утилита symlinks
- Заключение
How to find all symbolic links pointing to any file/directory inside a given directory
On this question or on this one (for example) you will get solutions on how to look for symlinks pointing to a given directory (let’s call it /dir1 ), while I am interested to symbolic links possibly pointing to any file/folder inside /dir1 .
I want to delete such directory but I am not sure that I am safe to do so, as on an other directory (let’s call it /dir2 ), I may have symlinks pointing to inner parts of /dir1 .
Further, I may have created these symlinks using absolute or relative paths. My only help is that I know the symlinks I want to check are on a mounted filesystem, on /dir2 .
4 Answers 4
You can find all the symbolic links using:
you might want to run this as root in order to get to every place on the disc.
You can expand these using readlink -f to get the full path of the link and you should be able to grep the output against the target directory that you are considering for deletion:
Using find / -type l -printf ‘%l\n’ doesn’t work as you get relative links like ../tmp/xyz which might be pointing to your target dir, but are not matched because they are not fully expanded.
In my case, the accepted answer wasn’t useful (because it didn’t output the link source). Here is what worked for me.
I worked around it using two -exec clauses:
- print -rC1 : prints its arguments r aw on 1 C olumn. Here, the arguments will be those generated from the following glob. Replace with ls -ld to get more information about each symlink¹
- **/ : any level of subdirectories (recursive globbing)
- * : file with any name (made of any number of characters, though zsh’s * like that of most shells will also allow non-characters).
- (. ) : glob qualifiers to further qualify the matching on other criteria than just the name of the files
- N : enable nullglob for that one glob (won’t fail if there’s no match, just pass an empty list to print which will print nothing).
- D : enable dotglob : also consider hidden files.
- @ : restrict to files of type symlink.
- e[‘code’] : select files for which the code evaluates to true. Inside the code , the file being considered is stored in $REPLY .
- $REPLY:P : gets the absolute and canonical (symlink free) path to the file (similar to what the realpath() standard function does).
- [[ string = pattern ]] returns true if the string matches the pattern (from ksh).
- /dir1(/*|) as a pattern matches on /dir1 alone or /dir1/ followed by anything.
¹ with the caveat that if there’s not matching file, that will list the current working directory. With ls , it would be better to remove the N glob qualifier
Depending on your circumstances, you could delete the directory, then delete any resultant invalid symlinks with the following:
The xtype test returns ‘l’ if the symlink is broken.
Not the answer you’re looking for? Browse other questions tagged symlink or ask your own question.
Linked
Related
Hot Network Questions
Subscribe to RSS
To subscribe to this RSS feed, copy and paste this URL into your RSS reader.
site design / logo © 2021 Stack Exchange Inc; user contributions licensed under cc by-sa. rev 2021.10.8.40416
By clicking “Accept all cookies”, you agree Stack Exchange can store cookies on your device and disclose information in accordance with our Cookie Policy.
Источник
How can I find broken symlinks
Is there a way to find all symbolic links that don’t point anywere?
will give me all symbolic links, but makes no distinction between links that go somewhere and links that don’t.
I’m currently doing:
But I’m wondering what alternate solutions exist.
11 Answers 11
I’d strongly suggest not to use find -L for the task (see below for explanation). Here are some other ways to do this:
If you want to use a «pure find » method, it should rather look like this:
( xtype is a test performed on a dereferenced link) This may not be available in all versions of find , though. But there are other options as well:
You can also exec test -e from within the find command:
Even some grep trick could be better (i.e., safer) than find -L , but not exactly such as presented in the question (which greps in entire output lines, including filenames):
The find -L trick quoted by solo from commandlinefu looks nice and hacky, but it has one very dangerous pitfall: All the symlinks are followed. Consider directory with the contents presented below:
If you run find -L . -type l in that directory, all /usr/share/ would be searched as well (and that can take really long) 1 . For a find command that is «immune to outgoing links», don’t use -L .
1 This may look like a minor inconvenience (the command will «just» take long to traverse all /usr/share ) – but can have more severe consequences. For instance, consider chroot environments: They can exist in some subdirectory of the main filesystem and contain symlinks to absolute locations. Those links could seem to be broken for the «outside» system, because they only point to proper places once you’ve entered the chroot. I also recall that some bootloader used symlinks under /boot that only made sense in an initial boot phase, when the boot partition was mounted as / .
So if you use a find -L command to find and then delete broken symlinks from some harmless-looking directory, you might even break your system.
Источник
Find out symbolic link target via command line
Say that I setup a symbolic link:
is there a way to see what the target of myothertextfile.txt is using the command line?
9 Answers 9
Use the -f flag to print the canonicalized version. For example:
From man readlink :
readlink is the command you want. You should look at the man page for the command. Because if you want to follow a chain of symbolic links to the actual file, then you need the -e or -f switch:
This will also work:
but readlink would be preferred for use in a script rather than parsing ls .
If you want to show the source and the destination of the link, try stat -c%N files* . E.g.
It’s not good for parsing (use readlink for that), but it shows link name and destination, without the clutter of ls -l
-c can be written —format and %N means “quoted file name with dereference if symbolic link”.
The readlink is a good thing, but GNU-specific and non cross platform. I used to write cross platform scripts for /bin/sh , therefore I’d use something like:
but these needs to be tested on different platforms. I think they’ll work, but don’t 100% sure for ls output format.
The result of ls can also be parsed within bash without depending on an external command like awk , sed or perl .
This bash_realpath function, resolves the final destination of a link (link→link→link→final):
If you can’t use readlink , then parsing the result of ls -l could be done like this.
The normal result would be:
So we want to replace everything before » -> » and the arrow included. We could use sed for this:
The question is not accurate enough to give a simple answer as the one of brian-brazil:
will indeed dereference every symlink involved in the path construct to the final target behind some_path .
But one level of cascading symlinks is just a particular case among others in a system, the general case being N levels of cascading symlinks. Look at the following on my system:
rwhich is my own recursive implementation of which that prints all of the intermediate cascading symlinks (to stderr) down to the final target (to stdout).
Then if I want to know what is:
the target of symlink /usr/bin/emacs**, the obvious answer to me is /etc/alternatives/emacs as returned by:
the final target behind cascading symlinks /usr/bin/emacs, the answer shall be /usr/bin/emacs24-x as returned by:
Источник
How to list all symbolic links in a directory
I have a symbolic link in my /var/www/ directory that links to WordPress. When I run the command ls -la from the /var/www/ directory the link to WordPress doesn’t show up. Is there a way to list all of the symbolic links that are in a directory?
9 Answers 9
Parsing ls is a Bad Idea®, prefer a simple find in that case:
To only process the current directory:
You can use grep with ls command to list all the symbolic links present in the current directory.
This will list all the links present in the current directory.
grep is your friend:
This will list lines starting with «l» which represent Links in the perms column in place of l use d for directories and — for files
This returns all symbolically linked items (both dirs & fns) in a directory:
However, in order to distinguish between actual symbolically linked item types:
Returns symbolically linked filename items only. And,
Returns symbolically linked dirname items only.
To view the symbolic links in a directory:
Open a terminal and move to that directory.
Type the command:
This shall long list all the files in the directory even if they are hidden.
The files that start with l are your symbolic link files.
Источник
Поиск и удаление битых символьных ссылок в Linux
Обновл. 14 Сен 2021 |
На этом уроке мы рассмотрим, как найти битые (т.е. неработающие) символьные ссылки, проанализировать их и удалить из Linux-системы, если это необходимо.
Символьные ссылки
Символьные ссылки (или «мягкие ссылки», «симлинки») представляют собой некое подобие ярлыков, которые могут указывать на файлы и каталоги. В окне файлового менеджера (или в консоле терминала) символьная ссылка выглядит так же, как и обычный файл или каталог. Файл или каталог, на который указывает символьная ссылка, может находиться в любом месте файловой системы.
Предположим, например, что в вашем домашнем каталоге под названием user есть символьная ссылка, указывающая на файл под названием text-file.txt, который находится где-то в другом месте файловой системы. Команды, которые вы применяете к символьной ссылке, автоматически применяются и к файлу, на который она ссылается, т.е. если вы попытаетесь использовать команду cat или less вместе с символьной ссылкой, то увидите содержимое файла text-file.txt.
Linux содержит большое количество символьных ссылок. Установщики приложений часто используют символьные ссылки для создания связей с исполняемыми файлами. При обновлении программного обеспечения, бинарный файл заменяется новой версией, и все символьные ссылки продолжают работать как и раньше до тех пор, пока имя нового файла совпадает со старым.
Мы можем легко увидеть некоторые символьные ссылки, применив к корневому каталогу команду ls . На тестовой машине с Debian 11 они выделены бледно-зеленым цветом:
Мы можем рассмотреть их подробнее, добавив опцию -l (long listing):
В начале каждой строки стоит буква l (link), которая обозначает, что данный объект является символьной ссылкой. Часть после -> показывает объект, на который указывает ссылка. В нашем примере целевыми объектами являются каталоги.
В символьных ссылках не используются права доступа к файлу (иными словами, они всегда имеют форму rwxrwxrwx ). В реальности, права доступа к символьным ссылкам определяются правами доступа к тому файлу, на который указывает символьная ссылка.
Создание символьных ссылок
Прежде, чем создавать символьную ссылку, предлагаю написать небольшую программку, которую мы свяжем с нашей ссылкой.
Для этого открываем терминал (например, с помощью сочетания клавиш Ctrl+Alt+T) и создаем новый файл ravesli.cpp:
Затем открываем этот файл любым текстовым редактором, например, nano:
Добавляем следующий код:
Нажимаем Ctrl+O для сохранения изменений и Ctrl+X для выхода из редактора.
Скомпилируем нашу программу при помощи компилятора g++:
g++ ravesli.cpp -o ravesli
Теперь переместим скомпилированный файл нашей программы к другим бинарным файлам в каталог /bin:
sudo mv ravesli /bin
Осталось создать символьную ссылку и связать её с /bin/ravesli. Для этого вводим команду ln (link) вместе с параметром -s (symbolic) и целевым объектом ( /bin/ravesli) с названием ссылки ( hello ):
ln –s /bin/ravesli hello
Мы только что связали бинарный файл с символьной ссылкой.
Битые символьные ссылки
Символьная ссылка становится битой (или «висячей»), если связанный с ней файл удаляется или перемещается в другое место. Если кто-то вручную удалит файл, не зная, что на него указывают символьные ссылки, то эти символьные ссылки больше не будут работать. Они будут похожи на дорожные знаки, указывающие на город, который снесли бульдозерами.
Для наглядной демонстрации такого поведения я специально создал символьную ссылку hello в каталоге
Видно, что ссылка указывает на программу под названием ravesli в каталоге /bin. Если мы запустим символьную ссылку, то запустится связанная с ней программа:
Далее обратимся к программе напрямую:
Как и ожидалось, мы получили тот же результат. А теперь давайте удалим файл программы:
sudo rm /bin/ravesli
Цвет символьной ссылки изменился. Она выделена красным, потому что Linux знает, что ссылка — битая. При этом система продолжает отображать объект, на который указывала ссылка, чтобы мы могли заменить файл, перекомпилировать программу или сделать другие, необходимые для восстановления символьной ссылки действия.
Обратите внимание, что если мы снова попытаемся запустить символьную ссылку, то получим ошибку ссылки, а не объекта, на который указывает ссылка:
Поиск битых символьных ссылок (команда find)
В большинстве современных версий команды find есть опция -xtype , которая упрощает поиск битых символьных ссылок. Использование команды find с опцией -xtype и флагом l (link) позволит искать и возвращать битые ссылки:
Стоит отметить, что по умолчанию поиск является рекурсивным, поэтому он автоматически выполняется для всех подкаталогов.
Если мы соединим вышеприведенную команду с командой wc -l (lines), то сможем подсчитать строки, что аналогично подсчету битых символьных ссылок:
find . -xtype l | wc -l
Как вы можете видеть, у нас есть 1 битая символьная ссылка.
Анализ битых символьных ссылок
Прежде чем удалять все битые символьные ссылки, внимательно изучите результаты команды find . Подумайте, есть ли веская причина для какой-либо из найденных символьных ссылок быть битой.
Иногда проблема может заключаться в символьной ссылке, а не в целевом файле: если символьная ссылка была создана неправильно, то она может ни на что не указывать, но при этом целевой файл существует. В таком случае пересоздание символьной ссылки станет решением проблемы.
Также возможно, что явно битая символьная ссылка используется в качестве чего-то другого, например, индикатора блокировки. Или что цель присутствует только периодически, и это ожидаемое (и желаемое) поведение конкретного программного обеспечения. Возможно, целевой файл копируется с другой машины или облака, выполняет свою функцию, а затем снова удаляется, только для того, чтобы быть замененным другой программой в следующем цикле.
Битая символьная ссылка может быть признаком неудачной установки программного обеспечения. В этом случае вместо удаления символьной ссылки вам следует либо исправить её вручную, либо повторить установку. Когда вы исправите необходимые битые ссылки, то повторите команду поиска битых ссылок. Если всё сделано правильно, исправленные символьные ссылки не должны будут больше отображаться в результатах поиска.
В целях безопасности лучше проводить удаление символьных ссылок в рамках ваших собственных каталогов. Будьте крайне осторожны при выполнении этих команд от имени root или в системных каталогах.
Удаление битых символьных ссылок
Опция -exec (execute) запускает некоторую команду, которая будет выполняться на результатах поиска, полученных от команды find . Мы собираемся использовать команду rm для удаления каждой поврежденной символьной ссылки. Часть <> заменяется именем битой символьной ссылки по мере обнаружения каждой из них с помощью команды find .
Мы должны использовать точку с запятой ( ; ), чтобы завершить список команд, которые мы хотим запустить при помощи -exec . Обратная косая черта ( \ ) используется для экранирования точки с запятой, благодаря чему она будет рассматривается как часть команды find :
find . -xtype l -exec rm <> \;
Как вы можете видеть, команда была выполнена без каких-либо признаков того, что что-то произошло. Чтобы убедиться, что битые ссылки удалены, мы повторяем команду для их поиска:
Нет никаких совпадающих результатов, что означает, что битые символьные ссылки были удалены.
Утилита symlinks
symlinks — это мощная утилита для управления и исправления битых символьных ссылок. Поскольку symlinks не входит в стандартную поставку большинства дистрибутивов Linux, то вам придется установить данный инструмент вручную.
Команда установки данной утилиты (в Debian 11) будет выглядеть следующим образом:
sudo aptitude install symlinks
Примечание: Если вы используете Ubuntu, то перед установкой symlinks вам нужно будет добавить репозиторий universe в список репозиториев вашей системы:
sudo add-apt-repository universe
После успешной установки symlinks вам необходимо проверить наличие битых ссылок в вашей системе. Для этого введите следующее:
Если в вашей системе присутствует битая (dangling) ссылка, вы получите вывод, который выглядит как на вышеприведенном скриншоте.
Символ . (точка) обозначает текущий рабочий каталог. Если вы хотите получить информацию о битых символьных ссылках, например, в каталоге /home, то можете сделать это, введя следующую команду:
Если в вашей системе присутствует битая ссылка, вы получите примерно следующий результат:
dangling: /home/diego/Документы/hello -> /bin/ravesli
Чтобы быстро удалить полученную ранее битую символьную ссылку, вы можете использовать флаг -d (delete):
Чтобы удалить битые символьные ссылки в каталоге /home, введите:
symlinks -d /home
На этот раз вывод будет не только перечислять найденные битые ссылки, но также сообщать, что ссылка теперь удалена, например:
dangling: /home/diego/Документы/hello -> /bin/ravesli
deleted: /home/diego/Документы/hello -> /bin/ravesli
Чтобы произвести рекурсивный поиск и удаление битых символьных ссылок в заданном каталоге, используйте флаги -dr (d = delete, r = recursive):
Заключение
Символьные ссылки важны для Linux, поскольку они облегчают процесс определения путей и управления ими на вашем компьютере. Но если об этом не позаботиться, то битые символьные ссылки могут занять огромный кусок вашего системного хранилища, и вы даже не узнаете об этом. В таких ситуациях в игру вступают такие утилиты, как symlinks и команда find . Также старайтесь всегда уделять время просмотру списка символьных ссылок, прежде чем запускать команду для их удаления.
Поделиться в социальных сетях:
Источник