Linuxでハードリンクを効率的に追跡する方法は?

Linuxでハードリンクを効率的に追跡する方法は?

ソフトリンクは元のファイルreadlinkなどを簡単に追跡できますが、元のファイルへのハードリンクを追跡するのに問題があります。

$ ll -i /usr/bin/bash /bin/bash  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /usr/bin/bash*
                   ^

上記は期待どおりに機能します。 - クール - >両方のファイルは同じinode 1310813を指します
(しかし、表示されるリンクの数は^1で表されます。その理由はGillesの答えで理解できます)。

$ find / -samefile /bin/bash 2>/dev/null
/usr/bin/bash

上記が予想されるので問題ありません。

$ find / -samefile /usr/bin/bash 2>/dev/null
/usr/bin/bash  

上記はいいえクール。元のファイルを追跡する方法またはハードリンクごとこの/usr/bin/bash記事を参考にしてもよろしいですか?

奇妙さ - 以下も役に立ちません。

$ find / -inum 1310813 2>/dev/null
/usr/bin/bash

答え1

まず、ハードリンクの場合、元のファイルはありません。すべてのハードリンクが同じように作成されます。

ls -lしかし、出力にリンク数が1で示されているように、ここには関連するハードリンクはありません。

$ ll -i /usr/bin/bash /bin/bash  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*  
1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /usr/bin/bash*

binを指すシンボリックリンクが原因で問題が発生しますusr/binbash利用可能なすべてのパスfind、次のオプションを使用してシンボリックリンクに従うように指示する必要があります-L

$ find -L / -xdev -samefile /usr/bin/bash 2>/dev/null
/usr/bin/rbash
/usr/bin/bash
/bin/rbash
/bin/bash

-xdev私はあなたのシステムが単一のファイルシステムにマウントされていることを知っているので、ここで使用します。これにより/dev、などの/proc問題が発生するのを防ぐことができます。/run/sys

答え2

/usr/bin/bash ファイルを参照として使用して元のファイルまたは各ハードリンクを追跡する方法

findGNU find(またはそのオプションがある他のバージョン-samefile)を使用してファイルシステムに/usr/bin/bashあると仮定すると、/次のようになります。

find / -xdev -samefile /bin/bash

ハードリンクはファイルシステムの境界を越えることができないために使用され-xdevます。リダイレクトしないでください。エラー:ディレクトリを閲覧する権限がない場合は、そのディレクトリの下にハードリンクがあり、それを見逃す可能性があります。

あなたが犯している間違いは、存在しない別のハードリンクを探していることです。実際には存在しないという情報があります。

1310813 -rwxr-xr-x 1 root root 1183448 Jun 18 21:14 /bin/bash*
                   ^

ハードリンク数は/bin/bash1です。

ファイルがあります//usr/bin/bashファイルが異なる理由で/bin/bashあります。/usr/bin/bash目次 /binそして/usr/bin同じファイルです。find / -samefile /bin/bashを指しているので、へのシンボリックリンクが/usr/bin/bashあります。より正確には、質問の情報に基づいて、これがディレクトリハードリンク(うまくサポートされておらず、ほとんど使用されていない機能)ではないと仮定すると、これが他のシンボリックリンクを指すシンボリックリンクである可能性があります。などは最終的に同等のルート(例:)として識別されますが、ほとんどがシンボリックリンクターゲティングである可能性が高いです。/bin/usr/bin/bin/bin/usr/bin/usr/bin///////usr/bin//usr/bin

システム全体でファイルへのすべてのシンボリックリンクを見つけることは特に効率的ではありません。たとえば、Linuxには、bashを実行している各プロセスへの/proc/*/exeシンボリックリンクであるファイルがあります。ディレクトリへのシンボリックリンクを見つけると、指摘されているように(chrootedプロセスを除く)無限再帰が発生します。/usr/bin/bash/bin/bash/proc/*/root/

両方のパスが同じファイルを指していることを確認する必要がある場合は、Linuxでは次のいずれかの方法を使用できます。

[ /bin/bash -ef /usr/bin/bash ]
test /bin/bash -ef /usr/bin/bash

-efPOSIXではありませんが、dash、bash、BusyBox、GNU coreutilsにあります)。異なるファイルが常に異なる正規名を持つという点で、ファイルの正規パスを取得する必要がある場合は、次のようにします。

readlink -f /bin/bash

(たとえば、同じネットワークロケーションが2つの異なる方法でマウントされていると、マウントされたディレクトリ全体で同じファイルが失われる可能性があります。)

関連情報