I need help in writing a script to create symbolic links. Here is a script that I have been running on background.

while true; do
    find $SOURCE -maxdepth 1 -type d -not -name "old.**" -exec ln -s -- {} "$DEST"/{} \;
    find $DEST -maxdepth 1 -type l -exec test ! -e {} \; -delete
sleep 30

Now I would like this script to perform couple more tasks.

  • Ignore already linked folders and folders with 'old.' prefix.
  • Remove symbolic-link from $DEST if the main folder is not available in $SOURCE.

Please help me to add those functionality on this script. Thanks.

  • What did your attempts look like? Possibly those will just need minor modifications to achieve what you want. – ErikE Dec 25 '13 at 16:12
  • My attempt is to compare 'find $DEST -maxdepth 1 -type l' with 'find $SOURCE -maxdepth 1 -type d -not -name "old.*"' and check if there are new folders in $SOURCE or links without main folders. Then create/remove links. The thing is I am not able to put it together here. – Himalay Dec 25 '13 at 19:00
  • @ErikE I wonder if you could help me with this? – Himalay Dec 27 '13 at 11:43
  • I believe this should not be too difficult and fun at the same time, however I'm holiday-stuck on iThings mostly. I would like to test before posting, so I'll likely post an answer eventually if it hasn't been solved :-) – ErikE Dec 27 '13 at 12:12
  • Now it almost works as I wanted but only thing is it tries to create links of all of those folders other than old.* in $SOURCE. :| – Himalay Dec 28 '13 at 10:58

I know this might be more cumbersome than you expected, but I would rewrite the -exec ... part as a separate script that gets one input parameter (the directory name to symlink to), and then checks if the symlink already exists (e.g. if [ -h "$DEST/$1" ] ...) and, if necessary, whether it resolves to a correct location (e.g. if [ $(readlink $DEST/$1) == $SOURCE/$1 ] .... If both conditions are true, we skip the file, otherwise the symlink is (re)created.

Then you call this script in the exec clase like this: find $SOURCE -maxdepth 1 -type f -not -name "old.**" -exec make-symlink.sh {} \;

A couple of further points:

  • The file names that find will substitute in place of {} will include $SOURCE: e.g. in your case the final exec command will look like this: ln -s -- /home/user/www/public /var/www/home/user/www/public. Solve this problem by using basename.

  • on some systems (OS X) the $SRC directory itself will be included in the list of directories find finds. This is probably not what you want. Solve this problem by removing first line of find output or by adding -not -name $(basename $SOURCE) clause.

Hope this helps.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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