web-dev-qa-db-ja.com

ハードリンクが元のスペースと同じスペースを取るように見えるのはなぜですか?

この辺りの良いQ&Aと このページ のおかげで、リンクが理解できました。ハードリンクは同じiノードを別の名前で参照しており、コピーは別のノードであり、名前も異なります。さらに、ソフトリンクは元のファイル名とパスをiノードとして持っているため、ファイルを移動するとリンクが壊れます。

そこで、私はいくつかのファイル(以下の "saluton_mondo.cpp")で学んだことをテストし、ハードリンクとソフトリンク、およびコピーを作成しました。

jmcf125@VMUbuntu:~$ ls -lh soft hard copy s*.cpp
-rw-rw-r-- 1 jmcf125 jmcf125 205 Aŭg 27 16:10 copy
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 hard
-rw-rw-r-- 2 jmcf125 jmcf125 205 Aŭg 25 13:34 saluton_mondo.cpp
lrwxrwxrwx 1 jmcf125 jmcf125  17 Aŭg 27 16:09 soft -> saluton_mondo.cpp

ただし、ハードリンクのサイズは元のリンクと同じであり、論理的にはコピーであることがわかりません。ハードリンクと元のファイルが同じiノードを共有し、データがあり、ファイル名のみが異なる場合、ハードリンクは205バイトではなく、その名前のスペースのみを使用するべきではありませんか?または、元のファイルのサイズがls -lh 戻り値?しかし、どうすればファイル名のスペースを知ることができますか? ここ ハードリンクにはサイズがないと表示されます。それらのファイル名は元のファイル名と一緒に保持されていますか?ハードリンクのファイル名はどこに保存されていますか?

14
JMCF125

ファイルはメタデータを持つiノードであり、その中にデータを検索する場所へのポインタのリストがあります。

ファイルにアクセスできるようにするには、ファイルをlinkディレクトリに移動する必要があります(ディレクトリをフォルダではなく電話ディレクトリと考えます)。つまり、1つ以上のディレクトリに1つ以上のエントリを追加します。 nameをそのファイルに関連付けます。

それらすべてのリンク、それらのファイル名は同じファイルを指します。オリジナルのものとリンクされているものはありません。これらはすべて、ディレクトリツリー内の同じファイル(同じiノード)へのアクセスポイントです。ファイルのサイズを取得すると(lstatシステムコール)、iノードに格納されている情報(上記のメタデータ)を取得します。どのファイル名、どのリンクを使用しているかは関係ありません。そのファイルを参照するために使用します。

対照的に、シンボリックリンクは別のファイル(別のiノード)であり、その内容はターゲットファイルへのパスです。他のファイルと同様に、これらのシンボリックリンクは、アクセスできるようにディレクトリにリンクする必要があります(名前が必要)。シンボリックリンクへのリンクを複数持つこともできます。つまり、シンボリックリンクに(1つ以上のディレクトリで)複数の名前を付けることができます。

$ touch a
$ ln a b
$ ln -s a c
$ ln c d
$ ls -li [a-d]
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 a
10486707 -rw-r--r-- 2 stephane stephane 0 Aug 27 17:05 b
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 c -> a
10502404 lrwxrwxrwx 2 stephane stephane 1 Aug 27 17:05 d -> a

ファイル番号10486707の上は通常のファイルです。現在のディレクトリの2つのエントリ(1つはa、もう1つはb)にリンクしています。 link countは2であるため、現在のディレクトリまたは他のディレクトリにそのファイルの名前が他にないことがわかります。ファイル番号10502404は別のファイルで、今回はタイプsymlinkが現在のディレクトリに2回リンクされています。その内容(ターゲット)は相対パス "a"です。

10502404が現在のディレクトリとは別のディレクトリにリンクされている場合は、通常、アクセス方法に応じて別のファイルを指します。

$ mkdir 1 2
$ echo foo > 1/a
$ echo bar > 2/a
$ ln -s a 1/b
$ ln 1/b 2/b
$ ls -lia 1 2
1:
total 92
10608644 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10504186 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a

2:
total 92
10608674 drwxr-xr-x   2 stephane stephane  4096 Aug 27 17:26 ./
10485761 drwxrwxr-x 443 stephane stephane 81920 Aug 27 17:26 ../
10539044 -rw-r--r--   1 stephane stephane     4 Aug 27 17:24 a
10539259 lrwxrwxrwx   2 stephane stephane     1 Aug 27 17:26 b -> a
$ cat 1/b
foo
$ cat 2/b
bar

ファイルには、それらをリンクするディレクトリ以外の名前は関連付けられていません。それらの名前が占めるスペースは、それらのディレクトリのエントリであり、ディレクトリのファイルサイズ/ディスク使用量に含まれます。

ファイルを削除するシステムコールはunlinkであることがわかります。つまり、ファイルを削除せず、ファイルが参照されているディレクトリからリンクを解除します。特定のファイルへのエントリがあった最後のディレクトリからリンクを解除すると、そのファイルは破棄されます(プロセスにファイルがない場合)開いた)。

16

ハードリンクは、基本的に、元のファイルです。したがって、報告されたサイズは、リンクされているファイルのサイズです。それらの名前のスペースだけを使用するsoftリンクです(ちょっと)。

ファイルシステムに関する限り、ハードリンクとオリジナルは同じものであり、同じiノードを指しているため、同じサイズが報告されます。

5
terdon