2つのファイルはハードリンクされていますか?


27

2つのファイルがコマンドラインからハードリンクされているかどうかを確認するにはどうすればよいですか?たとえば、何かがこれにリンクしています:

$ ls
fileA fileB fileC

$ is-hardlinked fileA fileB
yes

$ is-hardlinked fileA fileC
no

回答:


37

ほとんどのファイルシステム¹では、ファイルはそのiノード番号によって一意に決定されるため、チェックする必要があるのは、2つのファイルが同じiノード番号を持ち、同じファイルシステムにあるかどうかだけです。

Ash、ksh、bash、およびzshには、ファイルの等価演算子というチェックを行う構造があります-ef

[ fileA -ef fileB ] && ! [ fileA -ef fileC ]

より高度な場合にls -i /path/to/fileは、ファイルのiノード番号をリストします。df -P /path/to/fileファイルがどのファイルシステムにあるかを示します(2つのファイルが同じディレクトリにある場合、それらは同じファイルシステムにあります)。システムにstatコマンドがある場合は、おそらくiノード番号とファイルシステム番号を表示できます(システムstatによって異なりますので、ドキュメントを確認してください)。ディレクトリ内のハードリンクを一目で見たい場合は、ls -i | sort(おそらくawkにパイプされて)試してください。

¹ すべてのネイティブUNIXファイルシステム、およびNTFSなどの他のいくつかのシステム。ただし、CramFSなどのエキゾチックなケースではない場合があります。


また、FATベースの「クロスリンク」ファイルとして検出されるものには絶対に使用しないでください。
イグナシオバスケス-エイブラムス

4
がへのシンボリックリンクであるか、その逆の場合、または両方が同じファイルにリンクしている場合にも、(成功)をfileA -ef fileB返すことに注意してください。0fileAfileB
ジャンモエセン

提案したコマンドを実際にどのように実行しますか?[.bashrc -ef .bash / .bashrc]とこれのバリエーションを試しましたが、実際には機能しませんでした。
チャーリーパーカー14年

@CharlieParker [ .bashrc -ef .bash/.bashrc ]は正しいです。それは「本当に仕事しませんでした」なぜ文脈がなければ、もちろん、私は考えている-あなたは、あなたがすることなく、シェルを使用することができ、正確な結果をチェックしていない可能性があり、間違ったファイルを比較することができ-ef、...
ジル「SO-悪であるのをやめる」14年

2
@CharlieParkerコマンドは実際[にはであり、の同義語ですtest。しかし、man [またはman test外部コマンドのマニュアルページが表示されますが、ほとんどすべてのシェルにはわずかに異なるオプションを持つ組み込みコマンドがあるため、シェルのマニュアルでこれを調べる必要があります。
ジル 'SO-悪であるのをやめる' 14年

4
function is-hardlinked() {
    r=yes
    [ "`stat -c '%i' $1`" != "`stat -c '%i' $2`" ] && r=no
    echo $r
}

6
2つのファイルが異なるファイルシステム上にあるが、偶然同じiノードを持っている場合、これは誤検知になる可能性があることに注意してください。デバイス番号もテストする必要があります(stat -c %d)。Linuxを使用している場合(statコマンドが与えられた場合)、シェルは[ fileA -ef fileB ]これらすべてを直接行う必要があります。また、コマンドは、空白またはを含むファイル名で無条件に中断する\[?*、または-:で始まります。常に、コマンドの中断"$(stat -c %i -- "$1")")を二重引用符で囲みます。
ジル 'SO-悪であるのをやめる'

1
なぜ扱いにくいが移植性のある構成要素を使用し、次にfunction(ダッシュを含むために)許可された名前のPOSIX規則に違反する関数名を持つ、まったく移植性のないキーワードを使用するのですか?
チャールズダフィー

$1とを引用するのを忘れました$2。また$()、括弧によってコマンドの開始位置と終了位置が明確になり、ネストがより簡単になるため、バックティックの代わりに構文を使用することもできます。
ジョシュ

3

最初のポスターが示唆しているように、Linuxでは次のようなものに基づいてスクリプトを書くことができます。

stat -c '%i' fileA fileB fileC

4
これだけでは十分ではありません。異なるファイルシステム上にある場合でも、2つのファイルに同じ数が得られますが、偶然同じiノードがあります。デバイス番号もテストする必要があります(stat -c %d)。Linuxを使用している場合(statコマンドが与えられた場合)、シェルは[ fileA -ef fileB ]これらすべてを直接行う必要があります。
ジル 'SO-悪であるのをやめる'

0

GNU find(1)バージョン4.2.11以降では、これも使用できます。

if [ "yes" = "$(find fileA -samefile fileB -exec echo yes \;)" ]; then
    echo yes
else
    echo no
fi

if fileAfileBthen findと同じファイルである場合、「yes」が出力され、条件が真になります。

ファイル等価演算子を使用するのとは対照的に、-efこれは新しいプロセスを生成します。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.