Super User is a question and answer site for computer enthusiasts and power users. 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

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.

share|improve this question
They're referred to as "symbolic links" (as opposed to "hard links"). – Dennis Williamson Nov 16 '09 at 12:40
Righto, I knew I probably got the term wrong, thanks for the heads up – bguiz Nov 17 '09 at 11:24
Soft link is just fine as well, but with a space. :-) ( – Arjan Nov 17 '09 at 12:20
up vote 14 down vote accepted

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

for file in *
  if [ -h "$file" ]; then
    echo "$file"
share|improve this answer
2 - For conditional expressions makes for a better read than the man page. – Manos Dilaverakis Nov 16 '09 at 11:20
Thanks @Polsy and @Manos! test -h is what I wanted! – bguiz Nov 17 '09 at 11:28

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
share|improve this answer
I liked Polsy's answer better, still +1 for you, since I might need to do it outside a shell script some day. – bguiz Nov 17 '09 at 11:30
You don't necessarily need xargs. You could just use find . -maxdepth 1 -exec readlink {} \; – stib Dec 3 '11 at 6:23
True, @stib, but xargs is a lot faster on my Mac; see my edit. But I learned something new today: there's also + instead of \; (Though some claim that this has/had problems with grep.) – Arjan Dec 3 '11 at 8:31
interesting. thanks for sharing that. – stib Dec 5 '11 at 1:15

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .