/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"
問題が解決しました。