シンボリックリンク(symbolic link、ソフトリンクとも呼ばれる)とは、ファイルやディレクトリの場所(パス)を指し示すだけの特殊なファイルです。実体のデータは持たず、リンク先のパス文字列だけを保持するため、Windowsの「ショートカット」やmacOSの「エイリアス」に近い仕組みだとイメージすると分かりやすいです。Linux/Unix系OSでは ln コマンドで作成します。
結論:lnコマンドの使い方(最短)
書き方だけ確認したい場合は次の4行で足ります。指定する順番は「実体 → リンク名」で、cp や mv と同じ並びです。
ln -s 実体のパス リンク名 # シンボリックリンクを作る
ln -sf 実体のパス リンク名 # 既存のリンクを上書きして張り替える
ln -sfn 実体のパス リンク名 # 張り替え先がディレクトリを指すリンクのとき(重要)
ln 実体のパス リンク名 # ハードリンクを作る(-s なし)
| やりたいこと | コマンド |
|---|---|
| ファイルへのリンクを作る | ln -s /var/log/syslog syslog_link |
| ディレクトリへのリンクを作る | ln -s /app/releases/v2 current |
| ディレクトリへのリンクを張り替える | ln -sfn /app/releases/v3 current |
| リンク先を確認する | ls -l リンク名 / readlink -f リンク名 |
| リンクを削除する | rm リンク名(末尾のスラッシュは付けない) |
ln -sf でディレクトリへのリンクを張り替えようとして失敗する事故が非常に多いため、「リンクを強制的に上書きする」の節は必ず目を通してください。
シンボリックリンクとは
シンボリックリンクは、ファイルシステム上で「このパスを見に行ってください」という参照情報だけを持つ小さな特殊ファイルです。リンク自体には元ファイルの中身は含まれておらず、リンクを開くとOSが自動的にリンク先のファイルへアクセスします。同じ仕組みを持つ機能は、Windowsでは「ショートカット」、macOSでは「エイリアス」と呼ばれています。
シンボリックリンクの見分け方
ls -l で一覧表示すると、パーミッションの先頭が l になり、リンク名の後ろに -> でリンク先のパスが表示されます。
$ ls -l symlink.txt
lrwxrwxrwx 1 user user 12 Jul 20 02:11 symlink.txt -> original.txt
サイズ(この例では12バイト)はリンク先のパス文字列の長さであり、リンク元ファイルの実データサイズとは異なります。file symlink.txt でも「symbolic link to …」と表示され確認できます。
ハードリンクとの違い
| 項目 | シンボリックリンク | ハードリンク |
|---|---|---|
| 参照方法 | リンク先のパス文字列を保持 | 元ファイルと同じ inode を共有 |
| ファイルシステムをまたぐ | 可能 | 不可(同一ファイルシステム内のみ) |
| ディレクトリへのリンク | 可能 | 通常不可 |
| リンク元を削除した場合 | 参照先を失い「壊れたリンク」になる | 他のリンクが残っていれば実体にアクセス可能 |
| サイズ | パス文字列の分だけ(小さい) | 元ファイルと同じ |
メリットと使いどころ
実体ファイルを物理的に移動・コピーすることなく、複数の場所から同じファイルを参照できるのが最大のメリットです。設定ファイルの切り替えやデプロイ先バージョンの切り替え(後述の「よくある使い方」を参照)など、参照先だけを差し替えたい場面でよく使われます。一方で、リンク元を削除・移動すると参照が壊れる(broken link)点には注意が必要です。
lnコマンドでの作成方法(構文)
# ハードリンク作成
ln [オプション] 既存ファイル リンク名
# シンボリックリンク作成
ln -s [オプション] 既存ファイル リンク名
主なオプション一覧
| オプション | 説明 | 使用例 |
|---|---|---|
| (なし) | ハードリンクを作成 | ln file.txt link.txt |
-s | シンボリックリンクを作成 | ln -s /etc/nginx/nginx.conf conf_link |
-f | 既存のリンクを強制的に上書き | ln -sf new.conf conf_link |
-i | 上書き時に確認を求める | ln -si file.txt link.txt |
-n | シンボリックリンクを上書きする際にリンクをたどらない | ln -snf file link |
-r | -sと併用し、リンク先を自動で相対パスに変換 | ln -sr /app/config/prod.yml config.yml |
-t | リンク作成先のディレクトリを指定し、複数ファイルをまとめてリンク | ln -s -t dest/ a.txt b.txt |
-v | 作成したリンクを表示 | ln -sv file.txt link.txt |
-T | リンク名を必ず通常のファイルとして扱う | ln -sT file linkname |
実行例
ハードリンクを作成
ln original.txt hardlink.txt
出力(確認):
ls -li original.txt hardlink.txt
例:
123456 -rw-r--r-- 2 user user 100 Aug 21 10:00 hardlink.txt
123456 -rw-r--r-- 2 user user 100 Aug 21 10:00 original.txt
(同じ inode 番号を持つ)
シンボリックリンクを作成
ln -s /var/log/syslog syslog_link
出力(確認):
ls -l syslog_link
lrwxrwxrwx 1 user user 14 Aug 21 11:00 syslog_link -> /var/log/syslog
リンクを強制的に上書きする(-sf と -sfn の違い)
ln -s は、リンク名がすでに存在するとエラーになります。
$ ln -s new.conf conf_link
ln: failed to create symbolic link 'conf_link': File exists
そこで -f(force)を足すと、既存のリンクを消してから作り直します。リンク先がファイルの場合はこれで問題ありません。
ln -sf new.conf conf_link
ディレクトリを指すリンクは -sf だけでは張り替わらない
問題はリンク先がディレクトリの場合です。ln -sf は「リンク名」がディレクトリを指すシンボリックリンクだと、そのリンクをたどった先(ディレクトリの中)に新しいリンクを作ってしまいます。実際に再現します。
$ mkdir -p releases/v1 releases/v2
$ ln -s releases/v1 current
$ ls -l current
lrwxrwxrwx 1 mugi mugi 11 Aug 8 12:55 current -> releases/v1
# v2 に張り替えたつもりで実行する
$ ln -sf releases/v2 current
$ ls -l current
lrwxrwxrwx 1 mugi mugi 11 Aug 8 12:55 current -> releases/v1 <- 変わっていない!
$ ls -l releases/v1/
lrwxrwxrwx 1 mugi mugi 11 Aug 8 12:55 v2 -> releases/v2 <- 中に作られてしまった
current は v1 を指したままで、v1 ディレクトリの中に v2 という余計なリンクができています。エラーも警告も出ないため、デプロイスクリプトでこれをやると「切り替えたはずなのに古いバージョンが動き続ける」という分かりにくい障害になります。
解決策1:-n を足して ln -sfn にする
-n(--no-dereference)は「リンク名がシンボリックリンクだったとき、たどらずにリンク自体として扱う」オプションです。-sfn(-snf と書いても同じ)で意図どおりに張り替わります。
$ ln -sfn releases/v2 current
$ ls -l current
lrwxrwxrwx 1 mugi mugi 11 Aug 8 12:55 current -> releases/v2 <- 正しく張り替わった
解決策2:-T を使う(GNU coreutils)
-T(--no-target-directory)は「リンク名を必ず1つのファイル名として扱う」オプションです。意図がより明確になります。
$ ln -sfT releases/v1 current
$ ls -l current
lrwxrwxrwx 1 mugi mugi 11 Aug 8 12:55 current -> releases/v1
-T はGNU coreutils固有のオプションで、macOSやBSDの ln にはありません。移植性を重視するなら -sfn を使ってください。
| 書き方 | リンク先がファイル | リンク先がディレクトリ |
|---|---|---|
ln -s | 既存ならエラー | 既存ならエラー |
ln -sf | 正しく張り替わる | ディレクトリの中にリンクが作られる |
ln -sfn | 正しく張り替わる | 正しく張り替わる |
ln -sfT | 正しく張り替わる | 正しく張り替わる(GNU限定) |
迷ったときは常に ln -sfn を使うと覚えておけば、ファイル・ディレクトリのどちらでも安全です。
相対パスのシンボリックリンクを作成
ln -s ../config/settings.conf settings_link
相対パスを自動計算する(-r オプション)
-sと-rを組み合わせると、絶対パスで指定した場合でもリンク先を自動的に相対パスへ変換してくれます。手動で「../」の数を数える手間や計算ミスを防げます。
ln -srv /app/config/prod.yml releases/current/prod.yml
'releases/current/prod.yml' -> '../../app/config/prod.yml'
複数ファイルを1つのディレクトリへまとめてリンク(-t オプション)
-tでリンク作成先のディレクトリを指定すると、複数のファイルを1回のコマンドでまとめてリンクできます。ln 対象... ディレクトリの書き方(第3形式)でも同じ結果になります。
ln -s -t dest/ a.txt b.txt c.txt
# 上と同じ結果になる書き方
ln -s a.txt b.txt c.txt dest/
エラー例(存在しないファイルをリンク)
ln notfound.txt link.txt
出力例:
ln: failed to access 'notfound.txt': No such file or directory
よくある使い方
実行中バージョンを切り替える「currentリンク」パターン
デプロイ先ディレクトリを世代ごとに分けて配置し、current というシンボリックリンクだけを新しい世代に張り替えることで、無停止でのバージョン切り替えができます。
/app/releases/20260710/
/app/releases/20260711/
/app/current -> /app/releases/20260711/
# 新しいリリースに切り替え
ln -sfn /app/releases/20260711 /app/current
-n を付けることで、current がディレクトリを指すシンボリックリンクであっても、その中身ではなくリンク自体を張り替えられます(後述の「注意点」も参照)。
環境ごとに設定ファイルを切り替える
ln -sf config.production.yml config.yml
本番用・開発用など複数の設定ファイルを用意しておき、実際に読み込まれるファイル名(config.yml)へのリンク先だけを切り替える運用です。
シンボリックリンクの削除方法と注意点
シンボリックリンク自体を削除するには rm または unlink を使います。rm コマンドでリンクを削除しても、リンク元の実体ファイルは削除されません。
rm syslog_link
# または
unlink syslog_link
注意:リンク先がディレクトリの場合、末尾にスラッシュを付けて rm syslog_link/ のように削除しようとすると、シェルによってはリンクではなく参照先ディレクトリの中身に対して操作してしまうことがあります。ディレクトリを指すリンクを削除するときは、末尾のスラッシュを付けずに rm リンク名 と実行してください。
注意:-tで相対パスのファイルを指定すると、リンクの実体はリンク作成先ディレクトリの中に置かれるため、相対パスの基準がずれて壊れたリンクになることがあります。-tを使うときは対象ファイルを絶対パスで指定するか、-rを併用してください。
FAQ
シンボリックリンクとは一言でいうと何ですか?
ファイルやディレクトリの場所(パス)を指し示すだけの特殊なファイルです。実体のデータは持たず、Windowsの「ショートカット」やmacOSの「エイリアス」に近い仕組みです。Linux/Unix系OSではln -sコマンドで作成します。
ハードリンクとシンボリックリンク、どちらを使うべきですか?
ディレクトリや他のファイルシステムをまたいでリンクしたい場合は、シンボリックリンクを使います。同一ファイルシステム内でリンク先が消えても参照を維持したい場合はハードリンクが有効です。迷った場合は、汎用性が高く挙動が分かりやすいシンボリックリンク(ln -s)を選ぶのが無難です。
シンボリックリンクの参照先(絶対パス)を確認するには?
readlink -f を使うと、相対パスで作成したリンクでも参照先を絶対パスで表示できます。
readlink -f settings_link
ln -sf と ln -sfn はどう使い分けますか?
リンク先がファイルならどちらでも同じ結果になります。リンク先がディレクトリの場合は必ず -sfn を使ってください。-sf だけだと既存リンクをたどってディレクトリの中に新しいリンクを作ってしまい、張り替えが失敗したことに気づけません。常に ln -sfn と書く習慣にするのが安全です。
「File exists」と出て作成できません
指定したリンク名がすでに存在しています。上書きしてよければ -f を足してください。
$ ln -s new.conf conf_link
ln: failed to create symbolic link 'conf_link': File exists
$ ln -sfn new.conf conf_link # 上書きして張り替える
lnコマンドの引数はどちらが先ですか?
ln -s 実体 リンク名 の順です。cp コピー元 コピー先 や mv 移動元 移動先 と同じで、「すでにあるもの」が先、「これから作るもの」が後と覚えると間違えません。
「壊れたリンク(broken link)」を一覧表示するには?
参照先が存在しないシンボリックリンクをディレクトリ配下から探すには、以下のように find を使います。
find . -xtype l
関連コマンド
cp: ファイルをコピー(リンクではなく独立したファイル)readlink: シンボリックリンクの参照先を表示stat: inode 番号やリンク数を確認namei: パス上の各要素をシンボリックリンクごと辿って表示rm: ファイルやシンボリックリンクを削除
参考
- manページ: man7.org ln(1)
- GNU Coreutils: https://www.gnu.org/software/coreutils/

コメント