概要
本記事では、Linux におけるハードリンクとシンボリックリンクについて説明します。
ハードリンク (Hard Link)
ハードリンクは、Unix 系ファイルシステムで使われるリンクの一種で、同じファイルに対して複数の参照を持たせる仕組みです。 ハードリンクを作成すると、新しいファイル名が元のファイルと同じデータを指すようになります。これにより、1 つのファイルに対して複数のファイル名が存在することが可能となります。
inode
ファイルシステム内部では、ファイルやディレクトリの情報を inode (インデックスノード) という構造体に保存しています。 inode にはリンクカウントが含まれており、この数値はその inode を参照しているハードリンクの数を示します。リンクカウントが 1 以上である限り、inode に対応するデータは削除されません。すべてのハードリンクが削除されると、リンクカウントが 0 になり、その inode に対応するデータも削除されます。
ハードリンクの主な特徴
- inode の共有 ハードリンクによって参照されているファイルは、すべて同じ inode 番号を持ちます。 ファイルシステム上では「1 つの実体を複数の名前で参照している」状態と考えられます。
- ハードリンクの作成 ファイルのハードリンクを 1 つ作成すると、ファイルの実態に対して参照が 1 つ増えるため、リンクカウントは 1 増えます。
- ハードリンクの移動、リネーム ファイルを移動やリネームしても inode には影響ないため、実施後もファイルにアクセスできます。
- ファイルの削除 ファイルを削除した場合、リンクカウント (参照数) が 1 つ減少します。 リンクカウントが 0 になるまでは、ファイルデータ自体は消去されません。つまり、元ファイルを削除してもハードリンクが残っていれば、そのファイルデータは存続します。
- 同一ファイルシステム内限定 ハードリンクは別のパーティションやリモートマウントされたファイルシステムには作成できません。同一ファイルシステム内でのみ有効です。
- ディレクトリへのハードリンク 多くのシステムではディレクトリへのハードリンク作成は制限や推奨されない場合が多いです。 ディレクトリリンクが必要な場合は、通常シンボリックリンク (ソフトリンク) を利用します。
ハードリンクの作成する
以下の ln
コマンドを使うことでハードリンクを作成できます:
ln <元のファイル名> <リンク名 (ファイル名の別名)>
# 元ファイル file_original に対して file_hardlink というハードリンクを作成する
ln file_original file_hardlink
link
コマンドで作成することもできます:
link file_original file_hardlink
シンボリックリンク
シンボリックリンク (別名ソフトリンク) は、ファイルシステム上で参照先のパスを指し示す特殊なファイルです。実体ではなく、どのファイルまたはディレクトリに対するリンクなのかという文字列情報のみを保持しています。Windows のショートカットに似た仕組みです。
シンボリックリンクの主な特徴
パスの参照
シンボリックリンクは記載されたリンク先のパスを手掛かりにアクセスを行います。リンク先が存在しなくなった場合は、参照先にアクセスできなくなります。ファイルシステムを跨いで作成可能
シンボリックリンクは別のパーティションやネットワークドライブ上のファイルにもリンク可能です。これに対し、ハードリンクは同一ファイルシステム内でしか作成できません。ディレクトリへのシンボリックリンク
シンボリックリンクは、ファイルだけでなくディレクトリに対しても作成できます。
シンボリックリンクを作成する
シンボリックリンクを作成するには、ln -s
コマンドを使用します。
ln -s <リンク先のファイル> <リンク名>
ln -s /path/to/original/file.txt symlink_file.txt
このコマンドは、/path/to/original/file.txt
というファイルに対して symlink_file.txt
という名前のシンボリックリンクを作成します。
シンボリックリンクのリンク先を変更する
シンボリックリンクのリンク先を変更する場合、既存のシンボリックリンクを削除し、新しいリンクを再度作成します。
rm symlink_file.txt
ln -s /new/path/to/file.txt symlink_file.txt
シンボリックリンクのリンク先を取得する
シンボリックリンクが指しているファイルやディレクトリのパスを確認するには、readlink
コマンドまたは realpath
コマンドを使用します。
# シンボリックリンクを解決する。
readlink symlink_file.txt
# シンボリックリンクを解決し、絶対パスで表示する。
realpath symlink_file.txt
readlink
コマンドは、symlink_file.txt
が指しているリンク先のパスを表示します。
realpath
コマンドは、シンボリックリンクを解決し、絶対パスを表示します。
ls コマンドによる確認
ハードリンク
リンクカウントは ls -l
コマンドで確認できます。表示された出力の 2 カラム目がリンクカウントになります。
$ touch file1
$ ln file1 file2
$ ln -s file1 file3
$ ls -l
total 0
-rw-rw-r-- 2 ubuntu ubuntu 0 Feb 4 16:21 file1
-rw-rw-r-- 2 ubuntu ubuntu 0 Feb 4 16:21 file2
lrwxrwxrwx 1 ubuntu ubuntu 5 Feb 4 16:21 file3 -> file1
この出力では、file1
と file2
のリンクカウントが 2 になっていることがわかります。これは、これらのファイルが同じ inode を参照しており、ハードリンクが存在することを意味します。
inode 番号は ls -i
オプションで確認できます:
$ ls -i
8924674 file1 8924674 file2 8924675 file3
file1
と file2
の inode 番号が同じ 8924674 であることがわかります。
シンボリックリンク
シンボリックリンクの場合は、ls -l
コマンドで確認した際に、パーミッション rwxrwxrwx
の前の文字が l
になります。また、->
でリンク先が表示されます。
$ touch file1
$ ln file1 file2
$ ln -s file1 file3
$ ls -l
total 0
-rw-rw-r-- 2 ubuntu ubuntu 0 Feb 4 16:21 file1
-rw-rw-r-- 2 ubuntu ubuntu 0 Feb 4 16:21 file2
lrwxrwxrwx 1 ubuntu ubuntu 5 Feb 4 16:21 file3 -> file1
ls -F
コマンドを使用すると、ファイルの末尾に種類を表す記号が付加されます。@
マークの場合、そのファイルがシンボリックリンクであることを示しています。
$ ls -F
file1 file2 file3@
まとめ
ハードリンクとシンボリックリンクの違いをまとめると以下のようになります。
項目 | ハードリンク | シンボリックリンク |
---|---|---|
参照方法 | ファイルシステム内の同じ inode を共有 | 元ファイルやディレクトリのパスを参照 |
参照 | 元のファイルが削除されても、他にハードリンクが残っていればファイルは削除されない | リンク先のファイルが削除・移動されると参照できない |
ファイルシステムの制限 | 同じファイルシステム内のみ作成可能 | 別のファイルシステムやパーティションにも作成可能 |
ディレクトリへのリンク | 制限や管理者権限などが必要で、非推奨 | ディレクトリへのリンクも容易 |
コメント