ln コマンドの基本的な用法
Linux 環境において、ファイルへのリンクを作成するには ln コマンドを使用します。このコマンドは、既存のファイルに対して別の名前(リンク)を割り当てるために用いられます。
ln [オプション] 元ファイル リンクファイル
主要なオプションは以下の通りです。
-s:シンボリックリンク(ソフトリンク)を作成します。指定しない場合はハードリンクが作成されます。-f:強制オプション。リンク先に既にファイルが存在する場合、それを削除してからリンクを作成します。
ファイルシステムの内部構造
リンクの挙動を理解するには、Linux が採用する ext4 などのファイルシステムがデータをどのように管理しているかを把握する必要があります。パーティションは主に「メタデータ領域」と「データブロック領域」に大別されます。
メタデータ領域には inode(アイノード)と呼ばれる構造体が格納されます。inode はファイルの固有識別子であり、以下の情報を含みます。
- inode 番号
- アクセス権限(r, w, x)
- 所有者およびグループ情報
- ファイルサイズ
- タイムスタンプ(ctime, atime, mtime)
- 実データが保存されているブロック番号
重要な点として、ファイル名は inode には含まれていません。ファイル名はディレクトリファイルのデータブロック内で管理されます。
一方、データブロック領域にはファイルの実内容が保存されます。ブロックサイズは通常 4KB であり、ファイルサイズがこれを超える場合は複数のブロックが割り当てられます。これらのブロックは連続している場合もあれば、断片化されて分散している場合もあります。
ディレクトリとファイル名の関係性
ディレクトリもまたファイルの一種であり、その実データブロックには「ファイル名と inode 番号の対応表」が格納されています。ユーザーがファイル名を指定してアクセスする際、システムは以下の手順でファイルを特定します。
- ディレクトリファイルのブロックから、対象のファイル名に対応する inode 番号を取得する。
- 取得した inode 番号を元に、メタデータ領域から inode 情報を読み込む。
- inode 情報に含まれるブロック番号を参照し、実際のデータブロックへアクセスする。
つまり、ファイル名はあくまで inode を参照するためのラベルであり、実体へのアクセスは inode 番号を介して行われます。
ハードリンクの仕組み
ハードリンクは、複数のファイル名を単一の inode 番号に関連付ける機能です。異なるファイル名であっても、同じ inode を参照していれば、それらは同じ実データを指しています。
ハードリンクを作成すると、新しい inode やデータブロックは生成されません。代わりに、ディレクトリファイルのブロック内に「新しいファイル名と既存の inode 番号」のペアが追加されるだけです。
# 作業ディレクトリの作成
$ mkdir -p ~/project/data
$ cd ~/project/data
# 元ファイルの作成
$ echo "sample content" > source.txt
$ ls -li source.txt
123456 -rw-r--r-- 1 user user 15 Oct 20 10:00 source.txt
# ハードリンクの作成(同一ディレクトリ内)
$ ln source.txt hard_link.txt
$ ls -li
123456 -rw-r--r-- 2 user user 15 Oct 20 10:00 hard_link.txt
123456 -rw-r--r-- 2 user user 15 Oct 20 10:00 source.txt
# 別ディレクトリへのハードリンク作成
$ mkdir -p /var/tmp/backup
$ ln source.txt /var/tmp/backup/backup_link.txt
$ ls -li /var/tmp/backup/backup_link.txt
123456 -rw-r--r-- 3 user user 15 Oct 20 10:00 /var/tmp/backup/backup_link.txt
上記の例では、source.txt、hard_link.txt、backup_link.txt のすべてが inode 番号 123456 を共有しています。リンクカウント(リンク数)が作成ごとに増加していることにも注目してください。
ハードリンクの主な特性と制限は以下の通りです。
- 元ファイルまたはリンクファイルのいずれかを編集すると、両方の変更として反映されます(実データは共通のため)。
- ファイル名のいずれかを削除しても、リンクカウントが 0 にならない限りデータは消去されません。
- 異なるファイルシステム(パーティション)を跨いで作成することはできません。inode 番号はファイルシステム内で一意であるためです。
- ディレクトリに対してハードリンクを作成することはできません。循環参照などの複雑な問題を引き起こす可能性があるためです。
シンボリックリンクの仕組み
シンボリックリンク(ソフトリンク)は、元ファイルへの「パス」を保存する別のファイルです。ハードリンクとは異なり、シンボリックリンク自身専用の inode とデータブロックが新たに割り当てられます。
シンボリックリンクのデータブロックには、元ファイルへの絶対パスまたは相対パスが文字列として保存されます。アクセス時には、このパスを辿って実際のファイルを参照します。
# シンボリックリンクの作成
$ ln -s source.txt sym_link.txt
$ ls -li sym_link.txt
789012 lrwxrwxrwx 1 user user 10 Oct 20 10:05 sym_link.txt -> source.txt
この例では、sym_link.txt は独自の inode 番号(789012)を持っており、ファイルタイプを示す先頭の l がリンクファイルであることを示しています。
シンボリックリンクの特性は以下の通りです。
- 独自の inode とファイル属性を持ちます。
- 存在しないファイルやディレクトリに対してリンクを作成可能です。
- 異なるファイルシステムを跨いで作成できます。
- ディレクトリへのリンク作成が可能です。
- 元ファイルが削除されるとリンクは無効になり、デッドリンク(dangling link)となります。
両者の比較と動作差異
ハードリンクとシンボリックリンクの根本的な違いは、inode の共有有無とデータの実体にあります。
- inode 番号:ハードリンクは元ファイルと同一ですが、シンボリックリンクは独立しています。
- 跨ぎ越し:ハードリンクは同一パーティション内のみですが、シンボリックリンクはパーティションを越えられます。
- 対象:ハードリンクはファイルのみですが、シンボリックリンクはディレクトリも対象になります。
- 削除の影響:ハードリンクは元ファイルを削除しても残りのリンクからアクセス可能ですが、シンボリックリンクは元ファイルの削除で機能しなくなります。
ファイルの移動に関する挙動も異なります。ハードリンクは inode を直接参照しているため、元ファイルの名前変更や同一パーティション内での移動の影響を受けません。一方、シンボリックリンクはパスを保存しているため、元ファイルのパスが変更されるとリンクは切断されます。ただし、絶対パスで作成されたシンボリックリンク自体を移動させた場合は機能し続けますが、相対パスで作成されたリンクを移動すると、相対位置関係が変わるため参照先を見失う可能性があります。