web-dev-qa-db-ja.com

ハードリンクは通常のファイルとしてカウントされますか?

これを登録する方法はあるのかと思っていましたが、ほとんどの最新の検索エンジンは長さが約5語を超えるフレーズではうまく機能しないため、この検索エンジンに助けが必要です。

ファイルを特定のタイプとして登録し、それに応じて決定を行う必要があるbashスクリプトを作成しているので、これは不思議に思っていました。これは技術的には私のプロジェクトにとって重要ではありませんが、興味がありました。

また、それらが通常のファイルと見なされている場合、ls -iを解析せずにこれらのファイルがハードリンクされているかどうかを確認する方法はありますか?また、find -iコマンドを使用せずに、任意のファイルXが他の任意のファイルYにハードリンクされているかどうかを確認する方法はありますか?

21
Mr. Minty Fresh

Unixスタイルのシステムでは、ファイルシステムオブジェクトを表すデータ構造(つまり、データaboutファイル)は、いわゆる「iノード」に格納されます。

ファイル名はこのiノードへの単なるリンクであり、「ハードリンク」と呼ばれます。ファイルに付けられた最初の名前と後続のリンクに違いはありません。したがって、答えは「はい」です。ハードリンクは通常のファイルであり、実際、通常のファイルはハードリンクです。

lsコマンドは、ファイルへのハードリンクの数を示します。

例えば:

seumasmac@comp:~$ echo Hello > /tmp/hello.txt
seumasmac@comp:~$ ls -l /tmp/hello.txt 
-rw-rw-r-- 1 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

ここでは、/tmp/hello.txtというファイルを作成しました。 1からの出力のls -lは、このファイルへのハードリンクが1つあることを示しています。このハードリンクは、ファイル名自体/tmp/hello.txtです。

このファイルへの別のハードリンクを作成すると、次のようになります。

seumasmac@comp:~$ ln /tmp/hello.txt /tmp/helloagain.txt
seumasmac@comp:~$ ls -l /tmp/hello*
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/helloagain.txt
-rw-rw-r-- 2 seumasmac seumasmac 6 Oct  4 13:05 /tmp/hello.txt

これで、両方のファイル名がファイルへの2つのハードリンクがあることを示していることがわかります。これらはどちらも「適切な」ファイル名ではなく、どちらも同じように有効です。どちらも同じiノード(この場合は5374043)を指していることがわかります。

seumasmac@comp:~$ ls -i /tmp/hello*
5374043 /tmp/helloagain.txt  5374043 /tmp/hello.txt

これはディレクトリによって異なるという一般的な誤解があります。ディレクトリに対してlsによって返されるリンクの数は.および..を含むサブディレクトリの数であると人々が言うのを聞いたことがあります不正解 。または、少なくとも、それはあなたに正しい数を与えますが、それは間違った理由で正しいです!

ディレクトリを作成してls -ldを実行すると、次のようになります。

seumasmac@comp:~$ mkdir /tmp/testdir
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 2 seumasmac seumasmac 4096 Oct  4 13:20 /tmp/testdir

これは、このディレクトリへのハードリンクが2つあることを示しています。これらは:

/tmp/testdir
/tmp/testdir/.

/tmp/testdir/..notこのディレクトリへのリンクであることに注意してください。これは/tmpへのリンクです。そして、これは「サブディレクトリの数」というものが機能する理由を示しています。新しいサブディレクトリを作成すると、次のようになります。

seumasmac@comp:~$ mkdir /tmp/testdir/dir2
seumasmac@comp:~$ ls -ld /tmp/testdir
drwxrwxr-x 3 seumasmac seumasmac 4096 Oct  4 13:24 /tmp/testdir

/tmp/testdirディレクトリへの3つのハードリンクがあることがわかります。これらは:

/tmp/testdir
/tmp/testdir/.
/tmp/testdir/dir2/..

したがって、含まれる..エントリが原因で、新しいサブディレクトリごとにリンク数が1つ増えます。

38
seumasmac

ハードリンクは通常のファイルとしてカウントされますか?

ハードリンクは、リンクされているものとしてカウントされます。同じファイルシステム上の何にでもリンクできます。

mkdir test
cd !$

>file
ln -s file sym
mknod pipe p

ln file file2
ln -P sym sym2
ln pipe pipe2

ls -al

# sockets, too:
cat >tsock.c <<\EOD
#include <sys/socket.h>
#include <sys/un.h>
int main(int n, char **a)
{
        struct sockaddr_un test = { AF_UNIX, "socket" };
        int testfd = socket(AF_UNIX, SOCK_SEQPACKET, 0);
        bind(testfd,(struct sockaddr *)&test,sizeof test);
}
EOD
make tsock
./tsock

ln socket socket2

ls -al

# even devices if you want:
Sudo mknod mytty c 5 0
ln mytty mytty2
Sudo chmod 666 mytty

ls -al
# notice permissions are on an object not on the links to it:
echo Hi, Kilroy! >mytty2  

何かへのすべてのハードリンクは同等であり、(編集:非シンボリック)リンクがそこにある限り、根底にあるオブジェクトはそのまま残ります(開いているファイル記述子でさえ、非常にありがたく思っています)。

システムはディレクトリリンクにルールを適用し、ディレクトリへの名前付きリンクを1つ取得すると、システムは自動的にその埋め込まれた.リンクとサブディレクトリの..リンクを追加します(.が上記のlsには2つのリンクがあります)が、これは明示的なチェックです。ループを作らないという約束を約束する特権ユーザーは、新しいリンクを自分で追加できます。ファイルシステムは気にせず、任意のディレクトリグラフをうまく表すことができますが、誰もそれらを扱いたくありません。

この方法で機能しない(非UNIXの)ファイルシステムがたくさんあります。その中には、代替の「ハードリンク」として提供するものを呼び出すものも含まれます。 OS XはHFS +(それらをネイティブに持たない)で同等のものをまとめましたが、私が正しく思い出せば、ここでセマンティクスがどれほど忠実に保存されているかわかりません。

4
jthill