How can I check if there is a link from the current file on Linux? Say, I have:
touch foo
ln -s foo bar
ll foo bar
bar -> foo
foo
Now, I want to know, if there are any file linked from foo
:e.g.
$magic-command foo
foo<-bar
How can I check if there is a link from the current file on Linux? Say, I have:
touch foo
ln -s foo bar
ll foo bar
bar -> foo
foo
Now, I want to know, if there are any file linked from foo
:e.g.
$magic-command foo
foo<-bar
With GNU find
, you can do:
find -L / -xtype l -prune -samefile foo -exec ls -ld {} +
That will find all the files of type symlinks which eventually resolve to the same file as foo
. That will also include symlinks to symlinks or hardlinks to foo
1.
With -L
, symlinks are followed. We want that to find
files linked to foo
, but we don't want to follow symlink when descending the directory tree. Hence the -prune
that stops descending into symlinks.
With zsh
, you can do:
ls -ld /**/*(@De:'[[ $REPLY -ef foo ]]':)
If you're only interested in symlinks.
1
Finding only files that are symlinks to foo
would be more complicated. The -samefile
/-ef
compare the device and inode numbers returned by the stat()
system call, that is after all symlinks have been resolved (by the system). What you would want is check for links whose target's directory is the same as that of foo
and base name is foo
.
With zsh
, that would be:
zmodload zsh/zstat
links_to_thefile() {
local file link
file=${1-$REPLY}
zstat -L -A link +link -- $file || return
[[ $link:t = $thefile:t ]] || return
case $link in
(/*) file=$link;;
(*) file=$file:h/$link
esac
[[ $file:h -ef $thefile:h ]]
}
thefile=foo
ls -ld /**/*(@D+links_to_thefile)
Or with GNU tools (find
and shell (bash
)):
find / -type l \( -lname foo -o -lname '*/foo' \) -printf '%p\0%l\0' |
while IFS= read -rd '' file && IFS= read -rd '' link; do
[[ $link = /* ]] || link=${file%/*}/$link
[[ ${link%/*} -ef . ]] && printf '%s\n' "$file"
done