web-dev-qa-db-ja.com

多くの壊れたシンボリックリンクを「再リンク」するにはどうすればよいですか?

/homeの下にあるファイルへの一連のシンボリックリンクを含むディレクトリツリーがありますが、/home/mnt/homeに移動しました。シンボリックリンク。そのような機能は存在しますか、それを行うためにスクリプトを記述する必要がありますか?

例として、私は次のようなものを持っています:

[root@trees ~]# ls -l /mnt/home/someone/something
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/e

/mnt/home/someone/something/subdir:
total 4264
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 a -> /home/someone/someotherthing/subdir/a
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 b -> /home/someone/someotherthing/subdir/b
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 c -> /home/someone/someotherthing/subdir/c
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 d -> /home/someone/someotherthing/subdir/d
lrwxrwxrwx 1 jnet www-data      55 2011-08-07 13:50 e -> /home/someone/someotherthing/subdir/e

すべてのシンボリックリンクを見つけて同じ場所に再リンクするが、/mnt/homeの代わりに/homeの下にあるコマンドが欲しい

そのようなコマンドは存在しますか?

55
Josh

シンボリックリンクのターゲットを変更するコマンドはありません。削除して別のリンクを作成するだけです。 GNUユーティリティ(例:組み込みでないLinuxまたはCygwinのもとで)があると仮定すると、-lnameプライマリのfindはターゲットによってシンボリックリンクを照合し、readlinkはリンクの内容を読み取ります。未テスト:

find /mnt/home/someone/something -lname '/home/someone/*' \
     -exec sh -c 'ln -snf "/mnt$(readlink "$0")" "$0"' {} \;

これらのシンボリックリンクを相対的にすることをお勧めします。 symlinks と呼ばれる便利な小さなユーティリティがあり、多くのLinuxディストリビューションに存在します(当初はMark Lords、現在はJ. Brandt Buckleyが管理しています)。移動する前、または上記のように有効なリンクを復元した後、symlinks -c /mnt/home/someone/somethingファイルシステムの境界を越えない限り、指定されたディレクトリの下のすべての絶対シンボリックリンクを相対シンボリックリンクに変換します。

これは著者が要求している正確なものではないことを知っていますが、彼らはすでに答えを持っているようですので、質問に遭遇した私のような他の人のためにこれを追加します。

以下は、シンボリックリンクのターゲットの一部を置き換えることで修正できる壊れたシンボリックリンクの束など、より柔軟なソリューションが必要な場合に役立ちます。

例えば。ユーザー名の変更後、移動が完了した後、多くのリンクのターゲットで古いユーザー名を新しいユーザー名に置き換える。以下に示すreplace-simlinksというスクリプトを作成します。

#!/bin/bash
link=$1
# grab the target of the old link
target=$(readlink -- "$1")

# replace the first occurrence of oldusername with newusername in the target string
target=${target/oldusername/newusername}

# Test the link creation
echo ln -s -- "$target" "$link"

# If the above echo shows the correct commands are being issued, then uncomment the following lines and run the command again
#rm "$link"
#ln -s "$target" "$link"

次のコマンドで呼び出します:

find /home/newusername/ -lname '/home/oldusername/*' -exec ~/bin/replace-simlinks {} \;

これが誰かを助けることを願っています

編集:このスクリプトのキックスタート、およびリンクを相対にするためのsymlinksスクリプトの使用に関するヒントを提供してくれたGillesに感謝します。

13
Gerry

/home/mnt/homeへのシンボリックリンクとして作成すると、既存のすべてのシンボリックリンクが再び有効になります。

4
Keith Thompson