How to find all soft links (symbolic links) in current directory?

Question relates to shell-scripting in bash.

How to check with a script which files within the current directory are soft links?

In case I have used the wrong term, when I say soft links, I am referring to files created using ln -s.

The only thing I have managed to think of is to evaluate ls -la as an expression, and parse its results, but obviously this is not the best solution.


Solution 1:

See 'CONDITIONAL EXPRESSIONS' in man bash – in this case you want -h:

for file in *
do
  if [ -h "$file" ]; then
    echo "$file"
  fi
done

Solution 2:

You might not really need a script. To show any symbolic links in just the current folder, without recursing into any child folder:

find . -maxdepth 1 -type l -print

Or, to get some more info, use one of:

find . -maxdepth 1 -type l -exec ls -ld {} +
find . -maxdepth 1 -type l -print0 | xargs -0 ls -ld

To tell if a file is a symbolic link, one can use readlink, which will output nothing if it's not a symbolic link. The following example is not quite useful, but shows how readlink ignores normal files and folders. Use one of:

find . -maxdepth 1 -exec readlink {} +
find . -maxdepth 1 -print0 | xargs -0 readlink

Note that the above -exec ... + and xargs ... are much faster than -exec ... \;. Like:

time find /usr/bin -maxdepth 1 -type l -exec ls -ld {} \;
real 0m0.372s
user 0m0.087s
sys  0m0.163s

time find /usr/bin -maxdepth 1 -type l -exec ls -ld {} +
real 0m0.013s
user 0m0.004s
sys  0m0.008s

time find /usr/bin -maxdepth 1 -type l -print0 | xargs -0 ls -ld
real 0m0.012s
user 0m0.004s
sys  0m0.009s