Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

I frequently move directory trees to other locations or copy their tarballs to other machines, and I would like to have a method to check whether any symlinks in a directory tree A point to locations outside of A since these will be broken in the moved / copied directory.

share|improve this question
up vote 6 down vote accepted

You want a program called realpath, used in conjunction with find.


find . -type l -exec realpath {} \; | grep -v "^$(pwd)"
share|improve this answer

Use bindfs to create another view of that directory tree.

mkdir /tmp/view
bindfs /some/directory /tmp/view

Then use the symlinks utility (shipped by many distributions, or compile it from source) to detect cross-filesystem links.

symlinks -r /tmp/view | sed -n 's/^\(absolute\|other_fs\): //p'

(Note that parsing the output assumes that your symbolic links and their targets do not contain newlines, nor do paths to symbolic links contain the substring  -> .) That same utility can also convert absolute symlinks to relative (but you'd want to do that from the original location).

share|improve this answer

With zsh:

cd -P -- "$dir"
for i (**/*(ND@)) [[ $i:A = $PWD/* ]] || [[ $i:A = $PWD ]] || print -r -- "$i => $i:A"

Now, if the directory is /foo and you have /foo/bar that's a symlink to /foo/baz, that's a link whose target is in /foo, but once moved, the link will still be broken, so you may want also to match symlinks to absolute paths.

But even then, a bar => ../foo/baz in /foo would be an issue (false negative), so would a a => b where b is a symlink outside the tree (false positive, depending on how you want to look at it)

share|improve this answer

GNU coreutils provedes realpath, which resolves symlinks. With this, you could compare each symlink's target to the current working directory with something like:


find . | while read filename
  if realpath $filename | grep -E "^$PWD" > /dev/null
    echo 'this file is safe'
    echo 'this file links externally'
share|improve this answer
Several problems: no -type l, no -r option to read, IFS not sanitized for read, $filename not quoted, $PWD treated as a regular expression, paths with newline characters not accounted for, /foobar would be matched for $PWD == "/foo" – Stéphane Chazelas Oct 4 '12 at 21:38

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.