単純なLinuxコマンドを使用して絶対シンボリックリンクを相対シンボリックリンクに変換する

単純なLinuxコマンドを使用して絶対シンボリックリンクを相対シンボリックリンクに変換する

/home/user/system/bin、、、、、、/home...ディレクトリを含む標準のLinux/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

答え1

とともにsymlinks便利Mark Lordの作成(多くのディストリビューションで利用可能。ディストリビューションがそうでない場合源泉):

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
' _ {} +

答え2

純粋なbashとcoreutilsは、../パスに不要なsなしでシンボリックリンクを相対パスに変更します。

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 -fsテストecho ln -fs実行の実行

説明する:

  • target="$(realpath "$l")"- シンボリックリンク先の絶対パスを探す
  • ln -fs- シンボリックリンク生成(-s)、強制(-f)で既存のリンクを上書きする
  • realpath -s "$l"- シンボリックリンク自体の絶対パスを探す
  • dirname "$(realpath -s "$l")"- シンボリックリンクを含むディレクトリの絶対パスを探す
  • realpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"- シンボリックリンクに基づいてターゲットのパスを見つけます。つまり、絶対パスを相対パスに変換します。

答え3

sshfsは相対リンクの絶対値変換をサポートし、SSHを介してリモートディレクトリをマウントします。

コマンドは次のとおりです。はい

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

コマンド、特にコマンドは<placeholders>特定の状況に合わせて調整する必要があります。

答え4

find -lname "$PWD/*" | while read link ;do  
   target=$(readlink $link);
   relative_target=$(realpath $target --relative-to=$link/.. --no-symlinks --canonicalize-missing);
   ln --force --symbolic --no-target-directory $relative_target $link
done

"$PWD/*"現在の作業ディレクトリを指す絶対リンク変換のみを示します。

関連情報