I have a server that shares out user home folders over the network. Each user has a Cache folder. Sometimes a symlink is used to redirect this folder to the hard drive of whichever machine they are using (and sometimes that doesn't work and they have a broken symlink [which is a matter for another day].)

I'm trying to find out which users have symlinks and which don't. Within the shared folder, to get to the Cache folder you would substitute folders like so:

$GRADE/$USERNAME/Library/Caches

Right now I'm searching to see which users have symlinks and which do not. I've come up with:

cd /path/to/shared/home/folders
sudo find . -name "Caches" -exec ls -ld {} \;

and get results like this:

lrwxr-xr-x@  1 name0  ES_Students   27 Jan 18 11:05 ./CES_Grade_03/name0/Library/Caches -> /tmp/name0/Library/Caches
drwx------  11 name1  ES_Students  374 Dec  8 15:44 ./CES_Grade_03/name1/Library/Caches
lrwxr-xr-x@  1 name2  ES_Students   27 Feb 23 14:27 ./CES_Grade_03/name2/Library/Caches -> /tmp/name2/Library/Caches
drwx------  17 name3  ES_Students  578 Jan 25 11:13 ./CES_Grade_03/name3/Library/Caches
drwx------  12 name4  ES_Students  408 Mar 22 13:09 ./CES_Grade_03/name4/Library/Caches

but it nags at me that there must be a better way. Yes, it is good enough, and a one-off task, but I want to know how to do it right! Surely, I should be able to do something like:

cd /path/to/shared/home/folders
sudo ls -ld **/**/Library/Caches

I'm afraid that I don't know the proper syntax or if there is a recursive folder-replacing wildcard format in bash, and my google-fu failed me.

So, how do I properly formulate the search?

link|improve this question

51% accept rate
feedback

2 Answers

up vote 1 down vote accepted

Bash 4 has ** if you shopt -s globstar

globstar
                      If set, the pattern ** used in a filename expansion con‐
                      text will match a files and zero or more directories and
                      subdirectories.  If the pattern is followed by a /, only
                      directories and subdirectories match.

To find files that are symlinks to files (rather than directories):

find -maxdepth 1 -xtype f -type l -ls

To find broken symlinks:

find -L -type l
link|improve this answer
Wow. I'm still using Bash 3.2, but that command to find broken symlinks sounds great. – Clinton Blackmore Mar 23 '10 at 1:44
feedback

Dennis certainly got me on the right track. Here's what I'm ultimately using:

sudo find . -depth 3 -name Library -exec ls -ldGF {}/Caches \;

It only searches at a depth of 3 directories deep, looking for the Library folder (that every user has). It'll then list the entry for Caches in that folder, giving me:

  • a listing for a folder if it exists (in blue)
  • a line showing the symlink if it exists (in purple)
  • (theoretically) an error if no Cache folder exists at all

I tried:

sudo find . -depth 4 -name Caches -ls

and it is really close to what I wanted. It doesn't have any colouration, and will not tell me if a Cache folder is missing altogether.

I also really liked the search for broken symlinks, as follows:

sudo find -L . -depth 4 -type l -ls

I suppose the moral of the story is that I should've spent some more time looking through the find man page.

link|improve this answer
feedback

Your Answer

 
or
required, but never shown

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