하위 디렉토리에 많은 심볼릭 링크가있는 웹 응용 프로그램이 있습니다. 앱을 다른 디렉토리 구조로 이동해야하며 새 경로를 가리 키도록 모든 심볼릭 링크를 업데이트해야합니다. 예를 들면 다음과 같습니다.
Old Dir : /home/user/public_html/dev
새로운 Dir : /home/user/public_html/qa
Old Symlink : /home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/dev/images
새로운 Symlink :/home/user/public_html/qa/multisites/slave01/images -> /home/user/public_html/qa/images
문제는 다양한 디렉토리에 많은 것들이 흩어져 있다는 것입니다. 루트에서 재귀 적으로 검색하고로 가리키는 모든 심볼릭 링크를 다시 만들려면 어떻게 /dev/
해야 /qa/
합니까?
답변
이 bash 명령은 당신을 위해해야합니다 :
find /home/user/public_html/qa/ -type l -lname '/home/user/public_html/dev/*' -printf 'ln -nsf "$(readlink "%p" | sed s/dev/qa/)" "$(echo "%p" | sed s/dev/qa/)"\n' > script.sh
디렉토리에있는 대상과의 심볼릭 링크 인 디렉토리의 find
모든 파일을 식별하는 데 사용 되며 각 파일에 대해 링크를 해당 경로의 링크로 대체하는 bash 명령을 인쇄합니다 . 이것을 실행 한 후 생성 된 스크립트를qa
dev
qa/
bash script.sh
먼저 수동으로 검사하여 작동하는지 확인할 수 있습니다.
다음은 find
읽기 쉽 도록 위 명령 의보다 자세한 버전입니다 (실제로이 방법으로 쓸 필요는 없지만).
SRC_DIR="/home/user/public_html/qa"
OLD_TARGET="/home/user/public_html/dev"
SUB="s/dev/qa/"
find $SRC_DIR -type l \
-lname "$OLD_TARGET/*" -printf \
'ln -nsf "$(readlink "%p"|sed $SUB)" "$(echo "%p"|sed $SUB)"\n'\
> script.sh
답변
솔루션을 검색 할 때 다른 사람이이를 발견 한 경우 : 다음을 포함하는 “linkmod.sh”라는 파일을 작성하십시오.
#!/bin/sh
PATTERN1=`echo "$2"`
PATTERN2=`echo "$3"`
LINKNAME=`echo "$1"`
OLDTARGET=`readlink "$1"`
NEWTARGET=`echo "$OLDTARGET" \
| sed -e 's/'"$PATTERN1"'/'"$PATTERN2"'/'`
echo ln -nsf "$NEWTARGET" "$LINKNAME"
실행
find . -type l -print0 | xargs -0IX echo linkmod.sh X "pattern1" "pattern2"
필요한 경우 찾기에서 -lname 옵션을 사용할 수 있습니다.
참고 : echo는 하나를 제거하므로 sed에서 \를 필요로하는 문자보다 먼저 패턴에 2x \를 사용해야합니다. 예를 들어
find . -type l -print0 | xargs -0IX echo linkmod.sh X "folder\\ name\\/file" "folder2\\ name\\/file"
echo
ln 명령이 올바른 경우 마지막 행에서를 제거 하십시오.
답변
link_rename.sh
주어진 디렉토리에서 재귀 적으로 이름을 바꾸는 심볼릭 링크에 대한 bash 스크립트 를 만들었습니다.
#! /bin/bash
DIR=$1
OLD_PATTERN=$2
NEW_PATTERN=$3
while read -r line
do
echo $line
CUR_LINK_PATH="$(readlink "$line")"
NEW_LINK_PATH="$CUR_LINK_PATH"
NEW_LINK_PATH="${NEW_LINK_PATH/"$OLD_PATTERN"/"$NEW_PATTERN"}"
rm "$line"
ln -s "$NEW_LINK_PATH" "$line"
done <<< $(find "$DIR" -type l)
다음과 같이 실행될 수 있습니다 link_rename.sh /home/human/dir link1 link2
이 스크립트에는 3 가지 인수가 있습니다.
- 심볼릭 링크의 일괄 이름 바꾸기를 수행하려는 디렉토리
- 오래된 패턴. 여기
link1
에 교체 될 오래된 패턴이 있습니다. - 새로운 패턴. 교체 할
link2
새로운 패턴은 다음과 같습니다.link1
스크립트는 디렉토리의 모든 심볼릭 링크를 사용하여 find "$DIR" -type l
한 줄씩 재귀 적으로 처리하고 처리합니다.
$line
이름을 바꿔야하는 심볼릭 링크입니다
CUR_LINK_PATH
오래된 길이야
NEW_LINK_PATH
이전 링크 경로에서 문자열 대체를 수행하여 얻습니다.
이전 symlink가 제거되고 다음을 사용하여 새 symlink가 작성됩니다. ln -s "$NEW_LINK_PATH" "$line"
답변
트릭을 수행하는 것처럼 보이는 명령 행 PHP 스크립트를 작성했습니다.
<?php
//Run via command-line
$dir = new RecursiveDirectoryIterator('.');
foreach(new RecursiveIteratorIterator($dir) as $file) {
//$link = readlink($file);
if(is_link($file)) {
$old_link = readlink($file);
$new_link = str_ireplace("/joomla/", "/qa/", $old_link);
if($new_link != $old_link) {
exec('rm "'.$file.'"');
exec('ln -fs "'.$new_link.'" "'.$file.'"');
$new_link = readlink($file);
if($new_link == $old_link) {
echo $file."\t".$old_link."\t".$new_link."\n";
}
}
}
}
?>