ハードリンクとシンボリックリンク - lnコマンドとinodeの仕組み
この記事で達成できること
- ハードリンクとシンボリックリンクの違いを inode の観点で説明できる
ln/ln -sを状況に応じて正しく使い分けられる- リンク切れの原因を特定し回避できる
- ファイルシステム境界・ディレクトリに関するリンクの制約を理解できる
- 試験頻出の「ハードリンクは別 FS をまたげない」を根拠付きで答えられる
LPIC-1 主題 104.6「ハードリンクとシンボリックリンクを作成し、管理する」の中核。リンクの理解には inode(ファイルの実体を指す番号)の概念が不可欠。
ハードリンクとシンボリックリンクの判断
| 観点 | ハードリンク | シンボリックリンク |
|---|---|---|
| 作成コマンド | ln src link |
ln -s target link |
| 実体 | 同一 inode への別名 | 別 inode、パス文字列を保持 |
| 別ファイルシステム | 不可 | 可 |
| ディレクトリ対象 | 原則不可 | 可 |
| 元ファイル削除時 | データは残る | リンク切れになる |
ls -li の inode |
元と同一 | 元と異なる |
「別 FS をまたぐ」「ディレクトリを指す」必要があるならシンボリックリンク一択。同一 FS 内でファイル実体を共有しバックアップ的に多重参照したいならハードリンク。
手順
Step 1: inode とリンク数を確認する
echo "data" > original.txt ls -li original.txt
1310721 -rw-r--r-- 1 user user 5 May 17 10:00 original.txt
先頭の 1310721 が inode 番号、1 がハードリンク数。inode はファイルの実体(データブロック・メタ情報)を一意に指す。ファイル名は inode への参照に過ぎない。
Step 2: ハードリンクを作成する
ln original.txt hardlink.txt ls -li original.txt hardlink.txt
1310721 -rw-r--r-- 2 user user 5 May 17 10:00 original.txt 1310721 -rw-r--r-- 2 user user 5 May 17 10:00 hardlink.txt
両方が同じ inode 1310721 を指し、リンク数が 2 に増えた。どちらの名前から編集しても同じ実体を更新する。original.txt を削除しても inode はリンク数が 0 になるまで解放されない。
Step 3: シンボリックリンクを作成する
ln -s original.txt symlink.txt ls -li original.txt symlink.txt
1310721 -rw-r--r-- 2 user user 5 May 17 10:00 original.txt 1310733 lrwxrwxrwx 1 user user 12 May 17 10:01 symlink.txt -> original.txt
symlink.txt は別の inode 1310733 を持ち、-> original.txt というパス文字列を保持する。種別フラグが l(リンク)になっている点に注目。
Step 4: リンクの解決先を確認する
readlink symlink.txt readlink -f symlink.txt ls -L symlink.txt
original.txt /home/user/original.txt -rw-r--r-- 2 user user 5 May 17 10:00 symlink.txt
readlink はリンク先の生の文字列、readlink -f は最終的に解決された絶対パスを返す。ls -L はリンクをたどって実体の情報を表示する。
Step 5: 壊れたリンクを検出する
rm original.txt cat symlink.txt find . -xtype l
cat: symlink.txt: No such file or directory ./symlink.txt
元ファイルを削除すると symlink.txt はリンク切れ(dangling symlink)になる。find . -xtype l で壊れたシンボリックリンクを一覧できる。一方ハードリンクは元名を削除してもデータは保持される。
なぜハードリンクは別FSをまたげないのか
inode 番号はファイルシステムごとに独立した名前空間。/dev/sda1 の inode 100 と /dev/sdb1 の inode 100 は無関係な別実体。ハードリンクは「同一 inode への別名」であるため、異なるファイルシステム間では inode を共有できず作成が拒否される。
シンボリックリンクは inode ではなくパス文字列を保持する独立したファイル。パスは FS をまたいで表現できるため、別パーティション・別ディスク・存在しないパスすら指せる。代償としてリンク先が消えれば即座にリンク切れになる。この設計差が「ハードリンクは堅牢だが制約が多い、シンボリックリンクは柔軟だが脆い」というトレードオフを生む。
ディレクトリへのハードリンクが原則禁止なのは、ディレクトリ階層に循環参照が生じ find などのツリー走査が無限ループに陥るのを防ぐため。
トラブルシューティング
症状: ln でハードリンク作成が Invalid cross-device link で失敗する
原因: リンク元とリンク先が別ファイルシステム
確認:
df original.txt /mnt/other/
対処: 別 FS をまたぐ必要があるなら ln -s でシンボリックリンクを使う。df で両者が同一マウントか確認する。
症状: シンボリックリンクが意図せぬ場所を指す
原因: 相対パスでリンクを作成しリンク自体を移動した
確認:
readlink -f link
対処: 移動の可能性がある場合は絶対パスでターゲットを指定する(ln -s /abs/path/target link)。相対リンクはリンクの位置基準で解決される点に注意。
症状: ln -s で既存リンクを更新できない
原因: 同名のリンクが既に存在し File exists になる
確認:
ls -l link
対処: ln -sf target link で強制上書きする。ただし対象がディレクトリの場合は ln -sfn を併用しないとリンク先内部に作成される事故に注意。
作業完了チェックリスト
- [ ]
ls -liで inode 番号とリンク数を確認した - [ ] ハードリンク作成後にリンク数が増えることを確認した
- [ ] シンボリックリンクが別 inode・パス文字列保持であることを確認した
- [ ]
readlink -fで最終解決先を確認した - [ ]
find . -xtype lで壊れたリンクを検出した
まとめ
| 場面 | コマンド | 目的 |
|---|---|---|
| ハードリンク | ln src link |
同一 FS で実体共有 |
| シンボリックリンク | ln -s target link |
別 FS・ディレクトリ対応 |
| inode 確認 | ls -li |
リンク数・実体判定 |
| 解決先確認 | readlink -f |
最終的な絶対パス |
| 壊れリンク検出 | find . -xtype l |
dangling symlink 一覧 |
リンク機構はファイルシステム理解の要。次はシェル環境やプロセス優先度に進むと運用知識が連結する。