ハードリンクをシンボリックリンクに変換

ハードリンクをシンボリックリンクに変換

シンボリックリンクはハードリンクln -fはい)

両方のファイルがわかっていて自分が「オリジナルファイル」であることを定義している場合は、ハードリンク(ファイル名linkと)をシンボリックリンクにoriginal変換するのも簡単です。次の結果でlink->original簡単なスクリプトを簡単に作成できます。convert-known-hardlink-to-symlink

convert-known-hardlink-to-symlink link original
$ ls -li
3802465 lrwxrwxrwx 1 14 Dec  6 09:52 link -> original
3802269 -rw-rw-r-- 1  0 Dec  6 09:52 original

しかし、定義できるスクリプトがあれば非常に便利です。作業ディレクトリ(デフォルト./検索ディレクトリ検索場所(デフォルト/)同じinodeを持つファイルの場合、これらすべてのハードリンクをシンボリックリンクに変換します。

その結果、定義された作業ディレクトリ内のすべてのハードリンクされたファイルは、同じinodeを持つ最初のディスカバリファイルへのシンボリックリンクに置き換えられます。


始まりはfind . -type f -links +1 -printf "%i: %p (%n)\n"

答え1

これを行うためにスクリプトを作成しました。スクリプトは、作業ディレクトリ(オプションの2番目の引数)と同じソースディレクトリ(最初の引数)で見つかったすべてのハードリンクをシンボリックリンクに変換します。

https://gist.github.com/rubo77/7a9a83695a28412abbcd

テストを実行するための-nオプションがあります。これは実行するアクションのみを表示します。

主な部分:

$WORKING_DIR=./
#relative source directory from working directory:
$SOURCE_DIR=../otherdir/with/hard-links/with-the-same-inodes

# find all files in WORKING_DIR
cd "$WORKING_DIR"
find "." -type f -links +1 -printf "%i %p\n" | \
  while read working_inode working_on
do
    find "$SOURCE_DIR" -type f -links +1 -printf "%i %p\n" | sort -nk1 | \
      while read inode file
    do
        if [[ $inode == $working_inode ]]; then
            ln -vsf "$file" "$working_on"
        fi
    done
done

-links +1 --> 2つ以上のリンクを持つすべてのファイルを探します。ハードリンクされたファイルのリンク数は2つ以上です。

答え2

少なくともGNU find数字で(-inode)またはリンクを指定(-samefile)して、Inodeで検索することもできます。

したがって、次のものを使用できます。

find "$WORKING_DIR" -type f -links +1 | while read file
do
  find "$SOURCE_DIR" -samefile "$file" -exec ln -vsf '{}' "$file" \;
done

別のディレクトリを使用する必要があります。一方、lnファイル自体をリンクしようとすると文句が出ます。

また、絶対パスを提供する$SOURCE_DIRか、相対リンクを生成する-rオプションも使用する必要がありますln。そうしないと、リンクが壊れる可能性があります。

関連情報