다음은 상호 작용하려는 오래된 오류 심볼릭 링크를 재배치하는 작은 스크립트입니다.
#!/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
이는 심볼릭 링크의 경로를 대체하지 않습니다. 변수를 실제 경로 sed
(스크립트 끝)로 바꿀 때 제대로 작동하기 때문에 구문이 끔찍합니다.
right=$(echo "$wrongpath" | sed s'|/mnt/docs/dir2|/mnt/docs/dir1/dir2|') ;
변수를 올바르게 삽입하려면 어떻게 해야 합니까?
답변1
귀하의 질문에 대한 직접적인 대답은 "큰 따옴표 사용"입니다. 작은 따옴표는 모든 확장을 방지하기 때문입니다.
right=$(echo "$wrongpath" | sed "s|$oldtargetdir|$goodtargetdir|")
후행 세미콜론은 필요하지 않습니다. 항목이 같은 줄에 있는 경우에만 필요합니다. 따라서 done
레이아웃이 정통적이지 않고 done
일반적으로 한 줄에 있어야 하지만 앞의 세미콜론은 중복되지 않습니다.
다음을 사용할 수도 있습니다.
right="${wrongpath/$oldtargetdir/$goodtargetdir}"
이렇게 하면 하위 프로세스의 오버헤드가 방지됩니다.
답변2
변수는 작은따옴표로 확장되지 않고 큰따옴표로 묶입니다.
또한 이러한 간단한 교체를 수행하기 위해 sed가 필요하지 않으며 매개변수 확장을 사용할 수 있습니다.
right=${wrongpath/$oldtargetdir/$goodtargetdir}