간단한 Linux 명령으로 절대 symlink를 상대 symlink로 변환 나는 경로 내부의

나는 경로 내부의 완전한 하위 파일 시스템이 /home/user/system디렉토리와 표준 리눅스 구조를 포함을 /bin, /home, /root, /usr, /var, /etc, …

이 서브 파일 시스템에는 상대 또는 절대의 기호 링크가 있습니다. 상대 심볼릭 링크는 괜찮습니다 /home/user/system. 아래의 하위 파일 시스템 내에 있습니다. 그러나 절대 심볼릭 링크는 하위 파일 시스템 외부의 대상을 가리 키므로 문제가됩니다.

예를 들어 다음과 같이 절대 서브 링크를 가정합니다 (서브 파일 시스템 내부에서 볼 수 있음).

/usr/file1 -> /usr/lib/file1

전체 파일 시스템 에는 하위 파일 시스템 내부 의 파일 대신 하위 파일 시스템 외부의 /home/user/system/usr/file1파일을 가리키는 링크가 있습니다 ./usr/lib/file1/home/user/system/usr/lib/file1

모든 절대 심볼릭 링크를 상대 스크립트로 변환하는 단일 명령 줄 (rsync, chroot, find 등)과 같은 간단한 스크립트를 원합니다.

주어진 예에서, 상대 링크는

/usr/file1 -> ../usr/lib/file1



답변

Mark Lord 의 symlinks유틸리티 를 사용하여 (많은 배포판이 제공합니다.없는 경우 소스 에서 빌드하십시오 ) :

chroot /home/user/system symlinks -cr .

또는 readlink명령과 -lname술어 가있는 시스템 에서 find(경고 : 테스트되지 않은 코드) :

cd /home/user/system &&
find . -lname '/*' -exec ksh -c '
  for link; do
    target=$(readlink "$link")
    link=${link#./}
    root=${link//+([!\/])/..}; root=${root#/}; root=${root%..}
    rm "$link"
    ln -s "$root${target#/}" "$link"
  done
' _ {} +


답변

순수 bash 및 coreutils ../는 경로에 불필요한 s 없이 symlink를 상대로 변경 합니다.

find . -type l | while read l; do
    target="$(realpath "$l")"
    ln -fs "$(realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target")" "$l"
done

다음을 변경할 수 있습니다.

  • find .하는 find /path/to/directory그 디렉토리에 심볼릭 링크를 변환하는
  • ln -fsecho ln -fs마른 실행에 대한

설명:

  • target="$(realpath "$l")" -symlink 대상에 대한 절대 경로를 찾습니다
  • ln -fs– 심볼릭 링크 (생성 -s), 강제을 ( -f기존의 재 작성)
  • realpath -s "$l" -심볼릭 링크 자체에 대한 절대 경로를 찾습니다
  • dirname "$(realpath -s "$l")" -심볼릭 링크를 포함하는 디렉토리의 절대 경로를 찾습니다
  • realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target" -심볼릭 링크를 기준으로 대상의 경로를 찾습니다. 즉, 절대를 상대 경로로 변환합니다.

답변

이 배쉬 스 니펫이해야합니다. 첫 번째 양식은 수행 할 작업을 인쇄합니다. 두 번째는 그것을 할 것입니다. 나는 출력이 파괴적이므로 신중하게 검토 할 것 ln -f입니다. 기존 링크를 덮어 씁니다.

TOP=/home/user/system
cd $TOP
find * -type l -print | while read l; do echo ln -sf $TOP$(readlink $l) $l; done
find * -type l -print | while read l; do      ln -sf $TOP$(readlink $l) $l; done


답변

다음은 순수한 sh 솔루션입니다.

CD / 홈 / 사용자 / 시스템 및
찾기 -lname '/ *'|
읽는 동안 l; 해야 할 것
  echo ln -sf $ (echo $ (echo $ l | sed 's | / [^ /] * | / .. | g') $ (readlink $ l) | sed 's /.....//' ) $ l
완료 |
쉬


답변

상대 링크에서 절대 변환은 ssh를 통해 원격 디렉토리를 마운트하는 sshfs에 의해 지원됩니다.

명령은 다음과 같습니다

sudo sshfs <remote_user>@<remote_ip_address>:/ /home/<host_user>/mntpoint/ -o transform_symlinks -o allow_other

명령은 특히 <placeholders>특정 환경에 적합해야합니다.


답변