LinuxやUnix系OSでファイルやディレクトリへのショートカット(別名)を作成する際に欠かせないのが ln(リンク)コマンドです。日常の開発作業はもちろん、Webサーバーの設定ファイル切り替え(Nginx/Apache)や、Webアプリケーションの無停止デプロイにおけるバージョン切り替えなど、インフラ運用の現場で必須の基本コマンドです。
しかし、実務では「ln -s の引数はリンク元とリンク名どっちが先だっけ?」「既存リンクを強制上書きしようとして ln -sf を実行したらディレクトリの中に入れ子でリンクが作られてしまった」「相対パスでリンクを作ったらリンク切れ(赤字)になってしまった」といったトラブルや事故が頻発します。
本記事では、ln コマンドの基本構文からシンボリックリンクとハードリンクの徹底比較、失敗しないオプションの使い分け(特に -sfn の重要性)、実務で即コピペできる実践レシピ、初心者がハマりやすい罠とトラブルシューティングまで、実務目線で分かりやすく徹底解説します。
- 結論:lnコマンドの書き方早見表(最短で使いたい人向け)
- シンボリックリンクとハードリンクの違い(仕組み・比較表)
- 基本構文と引数の順序(絶対に間違えない覚え方)
- 主要オプション一覧と実務での使い分け(-s, -f, -n, -r, -t 等)
- 実務で使える実践レシピ(設定ファイル切替・無停止デプロイ等)
- 初心者がハマる5大トラブルと回避策(リンク切れ・上書き事故・削除罠)
- リンクの調査・確認に役立つ関連コマンド(readlink, realpath, find)
- よくある質問(FAQ)
1. 結論:lnコマンドの書き方早見表(最短で使いたい人向け)
書き方だけを今すぐ確認したい場合は、以下のコマンド例を参照してください。指定する順番は「実体(元ファイル/ディレクトリ) → 作成するリンク名」で、cp や mv と同じ並びです。
# 1. ファイルへのシンボリックリンク作成(最も基本)
ln -s /path/to/original.txt link.txt
# 2. ディレクトリへのシンボリックリンク作成
ln -s /var/www/releases/v1 /var/www/current
# 3. 既存のリンクを強制上書きして張り替える(ファイル対象)
ln -sf /path/to/new.txt link.txt
# 4. ディレクトリを指すリンクを安全・確実に上書き張り替え(超重要:-n を付与)
ln -sfn /var/www/releases/v2 /var/www/current
# 5. ハードリンクを作成する(-s なし)
ln original.txt hardlink.txt
# 6. リンク先(参照先の実体パス)を確認する
ls -l link.txt
readlink -f link.txt
# 7. シンボリックリンクを削除する(※末尾にスラッシュを付けない)
rm link.txt
# または
unlink link.txt
| やりたい操作 | 実行コマンド | 補足・注意点 |
|---|---|---|
| シンボリックリンク作成 | ln -s 実体パス リンク名 | 迷ったら基本はこれを使用 |
| ディレクトリリンク作成 | ln -s 実体ディレクトリ リンク名 | ディレクトリへのリンクも -s で可能 |
| ファイルリンクの上書き | ln -sf 実体パス リンク名 | 既存のリンクファイルを強制置換 |
| ディレクトリリンクの上書き | ln -sfn 実体ディレクトリ リンク名 | -n がないとディレクトリ内に入れ子作成される |
| 相対パスで自動リンク作成 | ln -sr 実体パス リンク名 | GNU coreutils環境で相対パスを自動計算 |
| 複数ファイルを一括リンク | ln -s -t リンク先ディレクトリ ファイル1 ファイル2 | -t でターゲットディレクトリを指定 |
| ハードリンク作成 | ln 実体ファイル リンク名 | 同一ファイルシステム内のファイルのみ作成可能 |
| リンク先の実体パス確認 | readlink -f リンク名 / realpath リンク名 | リンクを辿った最終的な絶対パスを表示 |
| シンボリックリンク削除 | rm リンク名 / unlink リンク名 | 末尾に / を付けない(実体保護のため) |
| リンク切れの一括検索 | find . -xtype l | 参照先が存在しない壊れたリンクを一覧表示 |
2. シンボリックリンクとハードリンクの違い
Linuxのリンクには「シンボリックリンク(Symbolic Link / ソフトリンク)」と「ハードリンク(Hard Link)」の2種類が存在します。両者の仕組みと特徴の違いを理解しておくと、トラブルを未然に防ぐことができます。
仕組みの違い:inode(インデックスノード)の共有か、パス参照か
Linuxファイルシステムでは、ファイルデータの実体や属性情報(サイズ、権限、更新日時、データブロックの配置場所など)は「inode(インデックスノード)」と呼ばれる管理番号で管理されています。私たちが普段見ているファイル名は、この inode 番号とファイルデータを結びつける「名札」に過ぎません。
- ハードリンク:元ファイルと「全く同じ inode 番号」を指す別の名札(別名)を作成します。どちらの名前からアクセスしても同じデータ実体に直接アクセスします。元ファイルを削除しても、リンクが1つでも残っていれば inode のリンクカウントが残るためデータは消えません。
- シンボリックリンク:独立した新しい inode を持ち、ファイルの中身として「リンク先のパス文字列(例:
/path/to/original.txt)」のみを格納した特殊ファイルです。WindowsのショートカットやmacOSのエイリアスと同じ仕組みです。リンク元が移動・削除されると参照先を見失い「リンク切れ(Broken Link)」になります。
シンボリックリンク vs ハードリンク 完全比較表
| 比較項目 | シンボリックリンク (ln -s) | ハードリンク (ln) |
|---|---|---|
| 参照方式 | リンク先のパス文字列を保持 | 同一の inode 番号を共有 |
| ディレクトリへのリンク | 可能 | 不可(無限ループ防止のため禁止) |
| 異なるパーティション/ストレージ間 | 可能(別マウント先もOK) | 不可(同一ファイルシステム内限定) |
| 元ファイルを削除した場合 | リンク切れ(参照不能・壊れたリンク) | リンクが残っていればデータは保持される |
| ファイルサイズ | パス文字列のバイト数のみ(数〜数十バイト) | 元ファイルと同じ(実体データを共有) |
inode番号 (ls -i) | 元ファイルと異なる新しいinode | 元ファイルと完全に同一のinode |
パーミッション表示 (ls -l) | 先頭が l(例: lrwxrwxrwx) | 先頭が -(通常のファイルと同じ) |
| 主な利用シーン | 設定切替、デプロイ、汎用ショートカット | バックアップツール、データ誤削除防止 |
実務での使い分けの結論:ディレクトリに対応しており、別ストレージを跨いでも動作し、ls -l でリンク先が一目で分かる「シンボリックリンク(ln -s)」を使用するのが99%のケースで最適です。ハードリンクは、バックアップツール(rsync の --link-dest 等)によるストレージ節約など、特定の用途に限られます。
3. 基本構文と引数の順序(絶対に間違えない覚え方)
ln コマンドの基本書式は以下の通りです。
# シンボリックリンクの作成構文
ln -s [オプション] <リンク元(実体パス)> <リンク先(作成するリンク名)>
# ハードリンクの作成構文
ln [オプション] <リンク元(実体ファイル)> <リンク先(作成するリンク名)>
引数の順序で迷ったときの覚え方
「リンク元とリンク名、どっちを先に書くんだっけ?」と迷ったときは、Linuxの基本コマンドである cp コマンド や mv コマンド を思い出してください。
cp <コピー元> <コピー先>mv <移動元> <移動先>ln -s <リンク元(実体)> <リンク先(リンク名)>
すべて「すでにあるもの(元)」が第1引数、「これから新しく作るもの(先)」が第2引数という統一されたルールになっています。
4. 主要オプション一覧と実務での使い分け
ln コマンドで使用頻度の高いオプションを整理しました。
| オプション | ロング名 | 機能・解説 | 実行例 |
|---|---|---|---|
-s | --symbolic | シンボリックリンクを作成する(指定しないとハードリンク) | ln -s file link |
-f | --force | 既存の同名リンク・ファイルを警告なしで強制上書き削除して作成 | ln -sf new_file link |
-n | --no-dereference | リンク先がディレクトリのシンボリックリンクである場合、参照先を辿らずリンクファイル自体として扱う | ln -sfn /app/v2 /app/current |
-r | --relative | リンク元への相対パスを自動計算してシンボリックリンクを作成(GNU coreutils) | ln -sr /var/log/app.log ./app.log |
-t | --target-directory=DIR | リンクを作成する対象ディレクトリを指定(複数ファイルを一括リンクする際に便利) | ln -s -t /usr/local/bin app1 app2 |
-T | --no-target-directory | 作成先の引数を常に通常ファイルとして扱う(ディレクトリ内の入れ子事故を完全防止) | ln -sfT new_dir link_dir |
-v | --verbose | 作成・更新されたリンクの情報を標準出力に表示 | ln -sv file link |
-i | --interactive | 既存のファイルが存在する場合に上書きの確認プロンプトを表示 | ln -si file link |
-b | --backup | 上書き時に既存ファイルのバックアップ(link~ など)を自動作成 | ln -sb file link |
5. 実務で使える実践レシピ(設定ファイル切替・無停止デプロイ)
サーバー構築や運用の現場でそのままコピー&ペーストして使える実用的なシナリオを紹介します。
レシピ1:Webサーバー(Nginx / Apache)の設定ファイル有効化
Nginx では、/etc/nginx/sites-available/ に設定ファイル実体を作成し、/etc/nginx/sites-enabled/ にシンボリックリンクを作成してサイトを有効化する構成が標準的です。
# Nginxの設定ファイルを有効化する
sudo ln -s /etc/nginx/sites-available/example.com.conf /etc/nginx/sites-enabled/example.com.conf
# 設定ファイルの構文チェックを行い反映
sudo nginx -t && sudo systemctl reload nginx
# サイトを無効化する場合(リンクのみ削除、実体は残る)
sudo rm /etc/nginx/sites-enabled/example.com.conf
sudo systemctl reload nginx
レシピ2:Webアプリケーションの無停止デプロイ(releases / current パターン)
Capistrano や Laravel Envoy、GitHub Actions などのデプロイフローで広く採用されている「世代管理デプロイ」です。新しいバージョン(例: v2.0.0)を別ディレクトリに用意し、current というシンボリックリンクを一瞬で切り替えることでダウンタイムゼロで切り替えます。
# ディレクトリ構造イメージ
# /var/www/app/
# ├── releases/
# │ ├── 20260801_v1/
# │ └── 20260826_v2/
# └── current -> /var/www/app/releases/20260826_v2/
# 新リリースへの安全な一発切り替え(必ず -sfn を使用!)
ln -sfn /var/www/app/releases/20260826_v2 /var/www/app/current
# 切り替え後の確認
ls -l /var/www/app/current
# 出力例: lrwxrwxrwx 1 app app 32 Aug 26 12:00 /var/www/app/current -> /var/www/app/releases/20260826_v2
万が一新バージョンに不具合が見つかった場合も、1行コマンドを実行するだけで瞬時に前バージョンへロールバックできます。
# 緊急ロールバック
ln -sfn /var/www/app/releases/20260801_v1 /var/www/app/current
レシピ3:複数ファイルの一括シンボリックリンク作成(-t オプション)
プロジェクト内の複数の実行スクリプトを一括で /usr/local/bin や作業ディレクトリにリンクしたい場合は、-t オプションを活用します。
# /opt/scripts 配下のスクリプト群を /usr/local/bin 配下に一括リンク
sudo ln -s -t /usr/local/bin /opt/scripts/deploy.sh /opt/scripts/backup.sh /opt/scripts/cleanup.sh
# 確認
ls -l /usr/local/bin/{deploy,backup,cleanup}.sh
レシピ4:容量の逼迫したディレクトリを別ストレージ(大容量ディスク)へ移行
ルートパーティションのログやアップロード画像ディレクトリが肥大化してディスク容量を圧迫した場合、別ドライブ(/mnt/storage/)にデータを移動させ、元の場所にシンボリックリンクを貼ることで、アプリケーション側のパス設定を変えずに容量問題を解決できます。
# 1. データを別ストレージにコピー(権限・属性を保持)
sudo cp -a /var/log/myapp /mnt/storage/myapp_logs
# 2. 元のディレクトリをリネーム(バックアップ)
sudo mv /var/log/myapp /var/log/myapp.bak
# 3. シンボリックリンクを作成
sudo ln -s /mnt/storage/myapp_logs /var/log/myapp
# 4. 正常に書き込めることを確認後、バックアップを削除
ls -ld /var/log/myapp
sudo rm -rf /var/log/myapp.bak
6. 初心者がハマる5大トラブルと回避策(トラブルシューティング)
ln コマンドでエンジニアが一度は遭遇する「定番の罠」とその解決策を解説します。
罠①:ln -sf でディレクトリリンクを張り替えると「中に作られる」罠
既存のシンボリックリンクを上書きしたい場合、-f を付けるのが一般的ですが、リンク先が「ディレクトリ」の場合は大事故の原因になります。ln -sf を実行すると、既存リンクがディレクトリを指しているため、リンク自体を上書きせず、「リンク先ディレクトリの中」に新しいシンボリックリンクを作成してしまいます。
# 再現実験:
$ mkdir -p app_v1 app_v2
$ ln -s app_v1 current
$ ls -l current
lrwxrwxrwx 1 user user 6 Aug 26 12:00 current -> app_v1
# v2 に張り替えたつもりで実行
$ ln -sf app_v2 current
# 確認してみると...
$ ls -l current
lrwxrwxrwx 1 user user 6 Aug 26 12:00 current -> app_v1 # <- まったく変わっていない!
$ ls -l app_v1/
lrwxrwxrwx 1 user user 6 Aug 26 12:00 app_v2 -> app_v2 # <- app_v1 の中に余計なリンクが作られた!
解決策:必ず -n(--no-dereference)を足して ln -sfn または ln -snf を使う!
# 正しい上書きコマンド
ln -sfn app_v2 current
$ ls -l current
lrwxrwxrwx 1 user user 6 Aug 26 12:01 current -> app_v2 # 正しく切り替わった!
「シンボリックリンクの張り替えは常に ln -sfn を使う」と指に覚え込ませておくと、ファイルでもディレクトリでも安全に上書きできます。
罠②:相対パス指定時の「リンク切れ(Broken Symlink)」事故
シンボリックリンクを相対パスで作成する際、「カレントディレクトリからの相対パス」と勘違いしてしまうミスが非常に多いです。シンボリックリンクの相対パスは、「シンボリックリンクが置かれるディレクトリ」を起点として解釈されます。
# 失敗例:カレントディレクトリから見て指定してしまう
# いま ~/project にいて、sub/ 配下に ~/project/config.json へのリンクを作りたい場合
$ ln -s config.json sub/link.json
# 確認(リンク切れで赤く点滅・表示される)
$ ls -l sub/link.json
lrwxrwxrwx 1 user user 11 Aug 26 12:05 sub/link.json -> config.json
# -> sub/config.json を探しに行ってしまい、ファイルが存在しないためリンク切れになる!
# 成功例1:リンク配置場所(sub/)から見た相対パスを指定する
$ ln -s ../config.json sub/link.json
# 成功例2:-r オプションで自動計算させる(おすすめ)
$ ln -sr config.json sub/link.json
# 成功例3:絶対パスで指定する
$ ln -s $(pwd)/config.json sub/link.json
罠③:ディレクトリリンク削除時に rm -rf link/(末尾スラッシュ)で中身を消す事故
ディレクトリを指しているシンボリックリンクを削除するとき、タブ補完などで末尾にスラッシュ(/)が付いた状態で rm を実行すると、環境やシェルによっては「リンク自体の削除」ではなく「参照先ディレクトリの中身の全削除」を行ってしまう致命的な事故につながります。
# 超危険:末尾にスラッシュを付けない!
rm -rf mylink/ # <- 実体ディレクトリの中身を巻き込んで消去するリスクあり!
# 安全な削除方法(スラッシュなし)
rm mylink
# さらに安全:unlink コマンドを使用(ファイル1つだけを解除する単機能コマンド)
unlink mylink
罠④:壊れたリンク(参照先不在)の検出と一括掃除
元ファイルを削除・移動したことでリンク先を失った「壊れたリンク(ダンangling / Broken link)」は、ディスク上に残り続けるとエラーの原因になります。find コマンド を使うと一括で検出・削除できます。
# カレントディレクトリ配下の壊れたシンボリックリンクを一覧表示
find . -xtype l
# 壊れたシンボリックリンクを一括安全削除
find . -xtype l -delete
# 削除前に確認したい場合
find . -xtype l -exec rm -i {} +
罠⑤:パーミッション(lrwxrwxrwx / 777)の誤解
シンボリックリンクを ls -l で確認すると、パーミッションが常に lrwxrwxrwx(全権限 777)と表示されます。「誰でも書き換えられる危険な状態なのでは?」と不安になる方がいますが、これは正常な動作です。
シンボリックリンク自体のパーミッションはLinuxカーネルによって完全に無視されます。 実際のアクセス権制御(読み書き・実行可否)は、リンク先の「実体ファイル」に設定されているパーミッション(chmod)によって厳格に判定されます。
なお、シンボリックリンク自体の所有者を変更したい場合は、chown に -h オプションを付けます(付けないと実体の所有者が変わります)。
# シンボリックリンク自体の所有者を変更
sudo chown -h www-data:www-data /var/www/current
7. リンクの調査・確認に役立つ関連コマンド
シンボリックリンクの確認やパス解決に役立つコマンドをまとめました。
| コマンド | 実行例 | 主な用途・得られる情報 |
|---|---|---|
ls -l / ls -li | ls -li link.txt | リンク先のパス表示、inode番号の確認 |
readlink | readlink -f link.txt | 多重リンクもすべて解決した最終的な絶対パスを表示 |
realpath | realpath link.txt | 相対パス・リンクを解決した正規化絶対パスを表示 |
file | file link.txt | ファイル形式(symbolic link to ...)を判定 |
stat | stat link.txt | リンク自体の inode、サイズ、最終アクセス時刻 |
namei | namei -l /path/to/link | パス上の各階層の権限とリンク追跡をツリー表示 |
8. よくある質問(FAQ)
Q1: なぜディレクトリのハードリンクは作成できないのですか?
ディレクトリのハードリンクを許可すると、ファイルシステム内に「循環参照(ループ)」が発生し、ディレクトリツリーを再帰探索するプログラム(find, du, rm -rf, ファイルシステムの整合性チェッカー fsck 等)が無限ループに陥ってシステムがクラッシュするリスクがあるためです。そのため、Linuxカーネルは root ユーザーであってもディレクトリのハードリンク作成を制限しています。ディレクトリのリンクには必ずシンボリックリンク(ln -s)を使用してください。
Q2: 元ファイルを移動・リネームするとシンボリックリンクはどうなりますか?
シンボリックリンクは単なる「パス文字列」を保持しているだけなので、元ファイルを移動またはリネームするとリンク先が見つからなくなり「リンク切れ」になります。元ファイルを移動した場合は、ln -sfn 新しいパス リンク名 でリンクを張り直す必要があります。
Q3: シンボリックリンクを Git でコミット・管理することはできますか?
はい、Git はシンボリックリンクを特殊なファイル形式(ファイルモード 120000)として正確に追跡・コミットできます。別の環境で git clone や git checkout を実行した際にも、OSがサポートしていれば自動的にシンボリックリンクとして復元されます(※Windows環境では権限設定が必要な場合があります)。
Q4: ln -sf と ln -sfn の使い分けはどうすればいいですか?
リンク先が通常ファイルであればどちらでも動作しますが、リンク先がディレクトリの場合は ln -sf だと意図しないディレクトリ内への作成事故が発生します。「シンボリックリンクの上書きは常に ln -sfn を使う」と統一しておくのが実務上のベストプラクティスです。
9. まとめ
ln コマンドは、Linux環境における柔軟なファイル管理・システム運用に欠かせない基本ツールです。以下の重要ポイントを押さえておけば、実務でのトラブルを100%防ぐことができます。
- 基本はシンボリックリンク(
ln -s)を使う:ディレクトリ対応・ストレージ跨ぎ対応で汎用性が高い。 - 引数は「実体 → リンク名」の順:
cpやmvと同じ「元 → 先」ルール。 - リンクの張り替え・上書きは必ず
ln -sfn:ディレクトリリンク上書き時の入れ子事故を完全に防止。 - リンク削除時は末尾
/を付けない:実体ディレクトリの誤削除を防ぐためrm linkまたはunlink linkを徹底。 - 壊れたリンクの掃除は
find . -xtype l -delete:リンク切れの定期チェックに活用。
日々の運用やデプロイスクリプトの作成で迷った際は、ぜひ本記事のチートシートや実践レシピをご活用ください。

コメント