2

I am relatively new to bash and am having some trouble with a script I am trying to write. After spending the last hour or so researching and trying new techniques, I am still unable to do what I would like.

My goal is this: I have a folder /Volumes/Server\ RAID/Photos where I keep all of my pictures. Each folder is titled YYYY-MM FolderName where there are sometimes spaces in FolderName. Within these folders are three folders: Raw, Edited, and Final. My goal is to, with a single bash script, create symbolic links on my Desktop for each Final folder AND rename it to its parent folder. Example: I would like /Volumes/Server\ RAID/Photos/2016-10\ Fleet\ Week/Final to have a symbolic link on the Desktop named 2016-10 Fleet Week.

I have tried many different varieties of the code I have posted down below, but the code I have included was the most concise code (although it didn't work).

Code description:

  1. cd to Desktop so that symlinks are created there
  2. use for loop to loop through folders
  3. create symlink - here is the problem: I need to include the folder name in the file path somehow, but also add \ before the spaces so that the command doesn't fail. HOWEVER, I have been getting error messages saying that there is no place called RAID/Photos which makes me think the script is stumbling on the first space, even with the backslash.
  4. Change name of Final symlink to the folder name. (I assumed I didn't need full directories here because I'm already in Desktop

    cd Desktop
    for f in /Volumes/Server\ RAID/Photos;
    do ln -s /Volumes/Server\ RAID/Photos/"$f"/Final
    mv Final $f
    done
    

QUESTION: Can someone please help me flush out this script? (I am mainly concerned with part three, but I wouldn't say no to help with the rest of it, either).

  • Put double quotes around the $f in the mv command. Even if it is properly escaped when put into the variable, it will expand into multiple words when you use it without quoting. – 0942v8653 Apr 17 '17 at 18:20
  • @user3439894 good point! Question edited to reflect intent (only symlinks for final folders) – NoahL Apr 17 '17 at 18:45
3

When running into troubles with shell quoting, it always help to add echo statements in suitable places in your script to see what's going on.

Let's look at this line by line:

for f in /Volumes/Server\ RAID/Photos;

This only runs once, and sets f to Volumes/Server RAID/Photos, which probably isn't what you want.

do ln -s /Volumes/Server\ RAID/Photos/"$f"/Final

f is set to the full path (see above), so this expands to

ln -s /Volumes/Server\ RAID/Photos//Volumes/Server\ RAID/Photos/Final

which (again) is not what you want to see here.

mv Final $f

See above :-)

There are various ways to tackle this, but in your case I would to something like the following (to get around the challenge of having to extract the directory name from the source path)

cd /Volumes/Server\ RAID/Photos/
for f in *; do
    if [ -d "$f" ]; then 
        if [ -d "$f"/Final ]; then
            ln -s "/Volumes/Server RAID/Photos/$f/Final" ~/Desktop/"$f"
        fi
    fi
done

The two ifs cover the cases where there are files in the source directory or the Final directory is missing.

You must log in to answer this question.

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