I have a series of directories, and images contained within:

/Volumes/library/Originals/2012/2012-05-13 Event/filename.jpg
/Volumes/library/Originals/2011/2011-03-11 Event/filename.jpg
/Volumes/library/Originals/2011/2011-01-12 Event/filename.jpg
/Volumes/library/Originals/2009/2019-07-11 Event/filename.jpg

Using bash, how can I create symbolic links to this directory tree in a single directory?


I need this to get my photos screen saver running on Mac OS X 10.8 which doesn't support recursive directories. I figure I can make a cron job that does this nightly. Thanks for your help.

closed as off topic by ewwhite, MDMarra, Iain Aug 6 '12 at 14:20

Questions on Server Fault are expected to relate to server, networking, or related infrastructure administration within the scope defined by the community. Consider editing the question or leaving comments for improvement if you believe the question can be reworded to fit within the scope. Read more about reopening questions here. If this question can be reworded to fit the rules in the help center, please edit the question.

  • I realize this may be a better question for stack overflow. Not sure how to close this question. – ensnare Aug 6 '12 at 13:54
  • 3
    You've got 3k rep and you don't know that we can migrate question from one site to another?? – Chris S Aug 6 '12 at 14:09
  • It's a better case for apple.stackexchange.com, to be honest. But I think your goals can be accomplished without descending to the Unix-level on your Mac system. – ewwhite Aug 6 '12 at 14:25

How about this:

for file in `find /Volumes/library/Originals -type f -name '*.jpg'`; do
  prefix=`basename $file .jpg`
  ln -s $file /image-links/$prefix$no.jpg
  no=$(($no + 1))

Quick note: you have to unset the IFS variable because MacOS X loves spaces within directory and file names. IFS set to nil prevents the "for" loop from dismantling the file names delivered by 'find' at the positions where spaces are. More about IFS in bash's man page, of course.

Quick note 2: I have a counter 'no' that runs from 1 up which is used to distinguish files with the same source names. A for loop runs over the results of 'find' which gathers all files under /Volumes/library/Originals that end in .jpg. Every file that is found as '/Volumes/library/Originals/something/something else/etc./<filename>.jpg' is then symbolically linked as '/image-links/<filename><no>.jpg'. 'basename' strips the full path from its directories and the .jpg suffix.

  • Can you explain the logic of your script? – ewwhite Aug 6 '12 at 14:08
  • If you want to do without all the IFS stuff, why not use find -print0, piping into while read -r -d ''? – slhck Aug 6 '12 at 14:28
  • There are million ways of doing things :) I am from the Solaris world where things are a bit more (for the lack of a better word) "pure". And that is reflected in my style. – mghocke Aug 6 '12 at 14:42

I think the approach here is wrong. You're looking to share photos from iPhoto to be used as a source for your desktop screensaver.

The way to do this cleanly is to create an album of the images you wish to use. It can also be a "Smart Album", which uses basic logic to determine its contents.

enter image description here

Then, in the Desktop and Screen Saver Preference Pane, choose iPhoto as your data source. If you have any problems selecting iPhoto, you may need to clear the .plist file associated with those preferences (Mountain Lion issue).

enter image description here


You'd have to add logic to deal with duplicate names but you could start with a very basic usage of find, like find ./ -name *jpg -execdir /tmp -exec /bin/ln -s '{}' \; executed from the directory where you want the links to appear.

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