Найти входящие символические ссылки

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

find GNU имеет -samefile тест. Согласно странице руководства:

 -samefile name File refers to the same inode as name. When -L is in effect, this can include symbolic links. 
 $ find -L / -samefile /path/to/file 

Это найдет все ссылки на /path/to/file , который содержит жесткие ссылки и сам файл. Если вам нужны только символические ссылки, вы можете индивидуально протестировать результаты find ( test -L ).

Вы должны прочитать, что такое эффекты -L , и гарантировать, что это не вызовет у вас никаких проблем с вашим поиском.

Примечание. Хотя в документации говорится, что он ищет файлы с тем же номером inode, он, похоже, работает в файловых системах.

например / home и / tmp являются отдельными файловыми системами

 $ touch ~/testfile $ ln -s ~/testfile /tmp/foo $ ln -s /tmp/foo /tmp/bar $ mkdir /tmp/x $ ln -s ~/testfile /tmp/x/baz $ find -L /tmp -samefile ~/testfile /tmp/bar /tmp/foo /tmp/x/baz 

Обратите внимание, как это возвращает / tmp / bar, который является символической ссылкой на / tmp / foo, которая является символической ссылкой на ~ / testfile. Если вы хотите найти прямые символические ссылки в ваш целевой файл, это не сработает.

Возможно, самый короткий путь:

 target="/usr/bin/firefox" # change me dir="/usr/bin" # change me realtarget="$(realpath "$target")" for file in $(find "$dir" -print); do realfile="$(realpath "$file")" test "$realfile" = "$realtarget" && echo "$file" done 

Но это не очень эффективно.

Если у вас нет realpath , установите его, например apt-get install realpath . Вы также можете использовать stat -N или ls -l или pwd -P для эмуляции realpath , но эти способы сложнее.

Кроме того, приведенный выше пример не будет обрабатывать имена файлов с пробелами в нем должным образом. Вот лучший способ сделать это. Обратите внимание, что IFS=$'\n' требует bash или zsh .

 OIFS="$IFS" IFS=$'\n' target="/usr/bin/firefox" # change me dir="/usr/bin" # change me realtarget="$(realpath "$target")" find "$dir" -print | while read -r file; do realfile="$(realpath "$file")" test "$realfile" = "$realtarget" && echo "$file" done IFS="$OIFS"