0

Here is a little script to retarget old-wrong symlinks that I want to make interactive.

#!/bin/bash
# retarget (broken) symbolink links interactively

echo -n "Enter the source directory where symlinks path should be retargeted > " 
  read response1                                                                   
  if [ -n "$response1" ]; then                                                     
    symlinksdirectory=$response1                                                   
fi                                                                                 

if [ -d $symlinksdirectory ]; then                                                 
  echo -n "Okay, source directory exists. Now enter 1) the symlinks OLD-WRONG target directory > "
  read response2                                                                   
  if [ -n "$response2" ]; then                                                     
    oldtargetdir=$response2                                                        
  fi                                                                               

  echo -n "$oldtargetdir - And 2) enter the symlinks CORRECT target directory > "
  read response3                                                                   
  if [ -n "$response3" ]; then                                                     
    goodtargetdir=$response3                                                       
  fi                                                                               

  echo -n "Now parsing symlinks in $symlinksdirectory to retarget them from $oldtargetdir to $goodtargetdir > "
  find $symlinksdirectory -type l | while read nullsymlink ;
  do wrongpath=$(readlink "$nullsymlink") ;
  right=$(echo "$wrongpath" | sed s'|$oldtargetdir|$goodtargetdir|') ;
  ln -fs "$right" "$nullsymlink" ; done                                            
fi

It does not replace the symlinks' path. My bad syntax as it works fine when replacing variables with real paths for sed (end of the script):

right=$(echo "$wrongpath" | sed s'|/mnt/docs/dir2|/mnt/docs/dir1/dir2|') ;

How should I insert variables properly?

2

The direct answer to your question is "use double quotes" because single quotes prevent all expansions:

 right=$(echo "$wrongpath" | sed "s|$oldtargetdir|$goodtargetdir|")

There's no need for the trailing semicolon; they're only necessary when something follows on the same line (so the one before done is not redundant, though the layout is unorthodox and the done should usually be on a line on its own).

You can also use:

right="${wrongpath/$oldtargetdir/$goodtargetdir}"

which avoids the overhead of sub-processes.

  • The overhead of subprocesses, is part of my learning process to the kiss graal ;) Also, I bet replacing find type -l ... nullsymlink with find ... -lname 'OLD-PATH' would give a better control on the retargeted links, but that's another post's story. – tuk0z Feb 10 '15 at 18:24
2

Variables are not expanded in single quotes, but they are in double quotes.

Moreover, you don't need sed for such a simple substitution, you can use parameter expansion:

right=${wrongpath/$oldtargetdir/$goodtargetdir}
  • Short, but very clear. Helped to understand Jonathan's first point! – tuk0z Feb 10 '15 at 17:44

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.