디렉토리에 대한 모든 심볼릭 링크를 찾고 대상을 다른 디렉토리로 변경

디렉토리에 대한 모든 심볼릭 링크를 찾고 대상을 다른 디렉토리로 변경

/home파일과 하위 디렉토리를 가리키는 심볼릭 링크가 많이 있습니다 /foo. 새 디렉토리를 타겟팅하고 싶습니다 /bar.

내 접근 방식은 모든 유효하지 않은 심볼릭 링크를 살펴보고 그들이 /foo.

sudo find . -type l -! -exec test -e {} \; -exec sh -c '\
   old_link_target=$(readlink "$0"); \
   new_link_target=${old_link_target//foo/bar}; \
   ln -snf $new_link_target $0' {} \;

그러나 유효하지 않은 심볼릭 링크에 초점을 맞추는 초기 단계를 포함하지 않는 보다 정확한 접근 방식을 원합니다. 따라서 이 질문에 대해서는 가정이 /foo남아 있으므로 다른 접근 방식이 필요합니다.

답변1

GNUly:

find . -lname '/foo*' -printf '%p\0%l\0' |
  awk -vRS='\0' '
    {
      getline target
      sub("^/foo", "/bar", target)
      printf("%s\0%s\0", target, $0)
    }' |
  xargs -r0n2 ln -sfT

또는 최신 GNU를 사용하십시오 sed.

find . -lname '/foo*' -printf '%l\0%p\0' |
  sed -z 's|^/foo|/bar|;n' |
  xargs -r0n2 ln -sfT

심볼릭 링크의 소유권에 영향을 미칠 수 있습니다(예: 심볼릭 링크가 자신이 소유하지 않은 디렉토리에 있지만 쓰기 권한이 있고 t비트가 설정된 경우(예 /tmp: )).

tar이를 방지하려면 대신 GNU를 사용할 수 있습니다 .

find . -lname '/foo*' -print0 |
  tar --null -T - -cf - --transform='s@^/foo@/bar@' |
  tar xpf -

답변2

다음은 매우 작은 테스트 세트입니다.

mkdir ./tmp1 ./tmp2    
touch ./tmp1/file1 ./tmp2/file2
ln -s ./tmp1 ./tmp3
ls -H ./tmp3

산출

file1

이제 나는...

mount --bind ./tmp2 ./tmp1
ls -H ./tmp3

산출

file2

만큼! 이제 한 번 가리킨 모든 링크는 ./tmp1자동으로 가리키게 됩니다 ./tmp2. 실제로 ./tmp1동일한 마운트 지점이기 때문입니다. ./tmp2하위 설치가 포함된 경우 아마도 다음을 수행할 것입니다.

mount --rbind ./tmp2 ./tmp1

그리고 트리를 재귀적으로 편집합니다 --bind mount. 이것은 Linux 커널 vfs의 표면도 아닙니다.공유 하위 트리 mount옵션.

Linux 시스템에서는 커널의 가상 파일 시스템 마운트 트리를 사용하여 파일 위치에 원자적으로 영향을 미칠 수 있으므로 파일이 가리키는 디렉터리에 대해 너무 신경 쓸 필요가 없습니다. 이는 사용자에게 달려 있습니다. 에서 모든 것을 관리할 수 있습니다 /etc/fstab.

>>/etc/fstab \
printf '%s %s none bind,defaults 0 0\n' \
    "/bar" "/foo"

문제가 해결되었습니다.

관련 정보