7

I can use

find /search/location -type l

to list all symbolic links inside /search/location.

How do I limit the output of find to symbolic links that refer to a valid directory, and exclude both, broken symbolic links and links to files?

muffel
  • 2,818

3 Answers3

7

With GNU find (the implementation on non-embedded Linux and Cygwin):

find /search/location -type l -xtype d

With find implementations that lack the -xtype primary, you can use two invocations of find, one to filter symbolic links and one to filter the ones that point to directories:

find /search/location -type l -exec sh -c 'find -L "$@" -type d -print' _ {} +

or you can call the test program:

find /search/location -type l -exec test {} \; -print

Alternatively, if you have zsh, it's just a matter of two glob qualifiers (@ = is a symbolic link, - = the following qualifiers act on the link target, / = is a directory):

print -lr /search/location/**/*(@-/)
  • find . -type l -exec sh -c 'find "$@" -L -type d -print' _ {} + yielded find: unknown predicate \-L'for me. moving the-Lin the second find invocation before the"$@"` made this work. – Wyatt Ward Aug 22 '21 at 16:29
1

Try:

find /search/location -type l -exec test -e {} \; -print 

From man test:

   -e FILE
          FILE exists

You might also benefit from this U&L answer to How can I find broken symlinks; be sure to read the comments too.

Edit: test -d to check if "FILE exists and is a directory"

find /search/location -type l -exec test -d {} \; -print 
KM.
  • 2,224
0

Here you go:

for i in $(find /search/location -type l); do 
  test -d $(readlink $i) && echo $i 
done
GMaster
  • 6,322
  • 1
    Don't parse the output of find. This breaks on file names containing whitespace or wildcard characters. For the same reason, put double quotes around variable substitutions. See http://unix.stackexchange.com/questions/131766/why-does-my-shell-script-choke-on-whitespace-or-other-special-characters?s=2|1.2316 – Gilles 'SO- stop being evil' Mar 22 '15 at 17:49