ディレクトリへのすべてのシンボリックリンクを探し、ターゲットを別のディレクトリに変更する

ディレクトリへのすべてのシンボリックリンクを探し、ターゲットを別のディレクトリに変更する

/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"

問題が解決しました。

関連情報