2つのパスが同じファイルを指しているかどうかを確認する

2つのパスが同じファイルを指しているかどうかを確認する

ファイルをバージョン管理下に置くために、ホーム ディレクトリから設定ディレクトリへのシンボリック リンクを再帰的に作成するスクリプトがあります。親ディレクトリ経由ですでにシンボリック リンクされているファイルをスキップしたいと思います。つまり、次のファイル/ディレクトリがあるとします。

~/foo/ -> ~/settings/foo/
~/settings/foo/
~/settings/foo/bar

~/foo/bar と ~/settings/foo/bar が同じファイルであることを確認するにはどうすればよいですか?

編集: ああ、さらに数分検索してみると、答え:readlink -f $path

答え1

2 つのファイルに同じデバイス ID と inode がある場合、それらは同じファイルです。statコマンドライン ツールを使用すると、これを簡単に見つけることができ、このソリューションは POSIX シェルに準拠しています。

if [ "$(stat -L -c %d:%i FILE1)" = "$(stat -L -c %d:%i FILE2)" ]; then
  echo "FILE1 and FILE2 refer to a single file, with one inode, on one device."
else
  echo "no match"
fi

-Lそれぞれのフラグは、シンボリックstatリンクされたファイルとハードリンクされたファイルの両方で機能することを意味します。

答え2

多くのシェルには組み込み-efの演算子test(またはその同義語[)があり、2つのパスが同じ既存ファイル(シンボリック リンクをたどる)。これには、bash、dash、pdksh、ksh88、ksh93、zsh が含まれますが、POSIX sh は含まれません。bash、ksh、zsh では、条件構文-efで を使用することもできます[[ … ]]

if ! [ "$1" -ef "$2" ]; then # $1 and $2 are different files

答え3

ソフトリンク ( で作成ln -s) の場合は を使用できますrealpath。ただし、これはハードリンクでは機能しません。

関連情報