パス/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
insideではなく、サブファイルシステムの外部のファイル/home/user/system/usr/lib/file1
を指します。
すべての絶対シンボリックリンクを相対シンボリックリンクに変換する単純なスクリプト、できれば単一のコマンドライン(rsync、chroot、find、...)が欲しいです。
与えられた例では、その相対リンクは次のようになります
/usr/file1 -> ../usr/lib/file1
symlinks
ユーティリティ によるMark Lord(多くのディストリビューションから提供されています。もしお持ちでない場合は、 source )からビルドしてください。
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なしでシンボリックリンクを相対に変更:
_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")"
-symlinkターゲットへの絶対パスを検索しますln -fs
_-シンボリックリンク(_-s
_)を作成し、既存の(_-f
_)を強制的に書き換えますrealpath -s "$l"
_-シンボリックリンク自体への絶対パスを検索しますdirname "$(realpath -s "$l")"
-シンボリックリンクを含むディレクトリへの絶対パスを検索しますrealpath --relative-to="$(dirname "$(realpath -s "$l")")" "$target"
-シンボリックリンクに対するターゲットのパスを検索します。つまり、絶対パスを相対パスに変換します相対リンクでの絶対変換は、sshを介してリモートディレクトリをマウントするsshfsでサポートされています。
コマンドは次のとおりです。
Sudo sshfs <remote_user>@<remote_ip_address>:/ /home/<Host_user>/mntpoint/ -o transform_symlinks -o allow_other
コマンド、特に<placeholders>
、特定の環境に適応するものとします。
これが純粋なshソリューションです。
cd/home/user/system && find。 -lname '/ *' | while read l; do echo ln -sf $(echo $(echo $ l | sed 's |/[^ /] * |/.. | g')$(readlink $ l)| sed 's/.. ... // ')$ l done | sh
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/*"
現在の作業ディレクトリ内を指す絶対リンクのみを変換することを意味します
このbashスニペットはそれを行う必要があります。最初のフォームはそれが何をするかを印刷します。 2番目はそれを行います。破壊的であるため、出力を慎重に確認します-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