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?
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 -L in the second find invocation before the "$@" made this work. 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 Here you go:
for i in $(find /search/location -type l); do test -d $(readlink $i) && echo $i done find. This breaks on file names containing whitespace or wildcard characters. For the same reason, put double quotes around variable substitutions. See unix.stackexchange.com/questions/131766/…