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


21

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

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

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


5
ハードリンクでは、「X」は実際には「Y」にリンクされていません。「X」と「Y」は同じファイルです。
ヨルダン

6
ディレクトリ内のすべての「通常のファイル」はハードリンクです。このようなファイルには複数のものがあります。
アンドリューヘンレ

@AndrewHenleうわー、良い点。それはまさに私が探していた種類のものなので、ありがとう。
ミントフレッシュ

2
@ Mr.MintyFresh特に、シンボリックリンクの場合のように、「オリジナル」と「リンク」の間に区別はありません。
Random832

回答:


38

Unixスタイルのシステムでは、(つまり、データのファイルシステムオブジェクトを表すデータ構造に関するファイル)は、「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/..なく、へのリンクであることに注意してください/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つずつ増加します。


メタデータ、iノード、ハードリンクの仕組みを理解しています。ハードリンクされたファイルが通常のファイルとしてカウントされるかどうかを明確にする必要がありました。これは、これに専用の列があるために答えが「はい」であることを示していますが、これはすべてのファイルにネイティブであることを暗黙的に示しています。申し訳ありませんが、私はこれに反対票を投じる必要があります:(
Mr. Minty Fresh

それは大丈夫です、私はそれが他の誰かにとって有用な情報になると確信しています。
seumasmac

ドットグロブハードリンクシステムを使用した興味深い編集では、これが行われることを知りませんでした。
ミントフレッシュ

ハードリンク==通常ファイルの段落を明確にしました。
seumasmac

1
特に次の文のように、「これらはどちらも「適切な」ファイル名ではなく、どちらも同じように有効です。」それはハードリンクを理解するための重要な要素です。非常にうまく書かれています。
ワイルドカード

4

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

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

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つのリンクがあることに注意してください)が、一部のmoddedでは明示的なチェックですループを作成しないことを約束することを約束するシステム特権ユーザーは、自分で新しいリンクを追加できます。ファイルシステムは気にせず、任意のディレクトリグラフをうまく表現できますが、誰もそれらを扱いたくありません。

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


./tsockとにかく、実際に何をしますか?
mikeserv

@mikeserv上記のmake-a-socketプログラムです。現在のディレクトリに「socket」という名前のソケットリンクをドロップするだけです。
jthill

わかりましたが、ソケットについてほとんど知らないことをもっと明確にすべきでした。リンクを十分に理解していると思うので、同じソケットに新しい名前を付けるだけですよね?ソケットなどには特別な意味はありませんね 私の無知についてすみません。
mikeserv

1
@mikeservソケットは純粋に実行時のエンティティです。 socket()実際のソケットを作成bind()し、特定の名前を付け、connect()作成したソケットを名前付きソケットに接続します。ソケットの種類は、名前の異なる種類を使用して、例えば、インターネットソケットは、インターネットアドレスを使用しますが、彼らはすべての共有、共通のAPI(含むread()write()、それはあなたがすることができないことを私は悲しいなりopen()、ファイルシステムのソケットとは、OSを持っているか、行うのlibc socket()connect()あなたのため) 。 man 7 socketさらに、すべてのネットワークプロトコルは、気まぐれなマンページを作成します。
jthill

1
@mikeserv参照してください、私はptyとptsを綴ることができ、おそらく天気の良い日にはptmxを綴ることもできますが、それだけです。:-)少なくとも5,0ノードは、私が見つけることができるすべての場所で機能します。これは、controlling-ttyデバイスタイプです。私はls -l / dev / ttyだけでそれを手に入れました。
jthill
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.