up vote 3 down vote favorite
2
share [g+] share [fb]

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.

link|improve this question

75% accept rate
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. :-) (en.wikipedia.org/wiki/Symbolic_link) – Arjan Nov 17 '09 at 12:20
feedback

2 Answers

up vote 8 down vote accepted

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

for file in *
do
  if [ -h $file ]; then
    echo $file
  fi
done
link|improve this answer
faqs.org/docs/bashman/bashref_68.html - 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
feedback

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
link|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
1  
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
feedback

Your Answer

 
or
required, but never shown

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