GNU/Linuxでハードリンクを削除する、とinodeの話
4 min read
こんにちは、無能です。
久しぶりにln
コマンドでリンクを作成しようとしたときに間違えて-s
オプションを消し忘れてハードリンクが作成されてしまったので不要なハードリンクを削除します。
ハードリンクを作成する
オプションナシでln
コマンドを実行するとハードリンクが作成されます。
alleycat:[haturatu]:~/git/hardlink$ ls
alleycat:[haturatu]:~/git/hardlink$ touch hardlink1
alleycat:[haturatu]:~/git/hardlink$ echo "You are an idiot" >> hardlink1
alleycat:[haturatu]:~/git/hardlink$ cat hardlink1
You are an idiot
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 12
drwxr-xr-x 2 haturatu haturatu 4096 1月 12 15:00 .
drwxr-xr-x 114 haturatu haturatu 4096 1月 12 15:00 ..
-rw-r--r-- 1 haturatu haturatu 17 1月 12 15:01 hardlink1
上記の様にファイルを作成してみました。
alleycat:[haturatu]:~/git/hardlink$ ln hardlink1 hardlink2
alleycat:[haturatu]:~/git/hardlink$ ls -la
合計 16
drwxr-xr-x 2 haturatu haturatu 4096 1月 12 15:02 .
drwxr-xr-x 114 haturatu haturatu 4096 1月 12 15:00 ..
-rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink1
-rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink2
これでハードリンクが作成されました。
そして、以下の標準出力を見てみます。
-rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink1
-rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink2
この-rw-r--r-- 2
の2
がハードリンクされている数です。ハードリンクされる前と比較して、値が増えていることが確認出来るかと思います。
そして、あくまでこれはリンクされているだけなのでディスク容量自体の逼迫しません。単一のデータを格納しており、inode
番号は同一となり同じファイルを示しています。
-i
オプションでinode
番号を確認します。
alleycat:[haturatu]:~/git/hardlink$ ls -lia
合計 16
13238408 drwxr-xr-x 2 haturatu haturatu 4096 1月 12 15:02 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096 1月 12 15:00 ..
13265123 -rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink1
13265123 -rw-r--r-- 2 haturatu haturatu 17 1月 12 15:01 hardlink2
inodeって?
あくまでこれはファイルシステムに依存するので上記はGNU/Linux
環境下でありBSD
系のファイルシステムであるとvnode
だったり、ZFSだとznode
等とちょっと変わっていますが歴史的に言えば元のUNIX
ファイルシステムを拡張したものだというイメージでよいのかなと思います。
そして、シンボリックリンクと違いハードリンクはhardlink1
を消してもhardlink2
は残りますし、hardlink2
を消してもhardlink1
は残ります。この点で言えばファイルシステムがそのファイル自体を管理しているから、という説明になりそうですがやはりちょっと難解ではありますよね。
しかし、こうみるとハードリンクは便利ですがシンボリックリンクは別のディスク上のファイルも参照できますがハードリンクの場合は別ディスク下には作成できません。
前述の説明も踏まえてシンプルに言えば、ファイルシステムは単一ディスクのinode
基準での話なので別ディスクとなるとそのファイルシステムの管轄外、レイヤー構造的に参照できません。
なので、別ディスク上に存在するならばシンボリックリンクを張る必要性が出てきます。
そして、ファイルシステム的にはこれを身近に使っているのはディスクの復旧、リカバリ作業時に過去のinode
情報から参照してどのinode
番号のファイルが作られたか、削除されたかどうかを識別しています。
ここでトラップですが、ファイルの上書きされるとこのinode
番号も更新されてしまいます。つまりはバックアップを取るスクリプト等のときはちゃんと上書き処理が入らないようなスクリプトを作る意識は必要かもしれません。(私は一度やらかしました)
同じinode番号のファイルを特定する
find
コマンドで確認ができます。
alleycat:[haturatu]:~/git/hardlink$ find . -inum 13265123
./hardlink2
./hardlink1
じゃあ、これでhardlink1
を削除してみます。
alleycat:[haturatu]:~/git/hardlink$ rm -i hardlink1
rm: 通常ファイル 'hardlink1' を削除しますか? y
alleycat:[haturatu]:~/git/hardlink$ ls -lai
合計 12
13238408 drwxr-xr-x 2 haturatu haturatu 4096 1月 12 15:23 .
11406555 drwxr-xr-x 114 haturatu haturatu 4096 1月 12 15:00 ..
13265123 -rw-r--r-- 1 haturatu haturatu 17 1月 12 15:01 hardlink2
alleycat:[haturatu]:~/git/hardlink$ cat hardlink2
You are an idiot
これで、ハードリンクされている値も1となり、元々ln hardlink1 hardlink2
でhardlink1
のリンクを作成して、hardlink1
と同じ情報を持っているhardlink2
が存在して同じデータを持っていることが確認出来ました。
活用的には
久しぶりに触りましたが、同じディスク内で大きなファイルをコピーさせたいけどディスク消耗は減らしたい場合はハードリンクしたほうがよさそうですね。
まあ、そんなに意識して使うものでもないかもしれませんがファイルシステムの構造がちょっとわかるようなものなので面白いものかなと思います。
それではまた。
よろしくおねがいします。