lnコマンドの使い方|シンボリックリンクの作成とln -sfnによる張り替え

コマンドリファレンス

シンボリックリンク(symbolic link、ソフトリンクとも呼ばれる)とは、ファイルやディレクトリの場所(パス)を指し示すだけの特殊なファイルです。実体のデータは持たず、リンク先のパス文字列だけを保持するため、Windowsの「ショートカット」やmacOSの「エイリアス」に近い仕組みだとイメージすると分かりやすいです。Linux/Unix系OSでは ln コマンドで作成します。

  1. 結論:lnコマンドの使い方(最短)
  2. シンボリックリンクとは
    1. シンボリックリンクの見分け方
    2. ハードリンクとの違い
    3. メリットと使いどころ
  3. lnコマンドでの作成方法(構文)
  4. 主なオプション一覧
  5. 実行例
    1. ハードリンクを作成
    2. シンボリックリンクを作成
    3. リンクを強制的に上書きする(-sf と -sfn の違い)
      1. ディレクトリを指すリンクは -sf だけでは張り替わらない
      2. 解決策1:-n を足して ln -sfn にする
      3. 解決策2:-T を使う(GNU coreutils)
    4. 相対パスのシンボリックリンクを作成
    5. 相対パスを自動計算する(-r オプション)
    6. 複数ファイルを1つのディレクトリへまとめてリンク(-t オプション)
    7. エラー例(存在しないファイルをリンク)
  6. よくある使い方
    1. 実行中バージョンを切り替える「currentリンク」パターン
    2. 環境ごとに設定ファイルを切り替える
  7. シンボリックリンクの削除方法と注意点
  8. FAQ
    1. シンボリックリンクとは一言でいうと何ですか?
    2. ハードリンクとシンボリックリンク、どちらを使うべきですか?
    3. シンボリックリンクの参照先(絶対パス)を確認するには?
    4. ln -sf と ln -sfn はどう使い分けますか?
    5. 「File exists」と出て作成できません
    6. lnコマンドの引数はどちらが先ですか?
    7. 「壊れたリンク(broken link)」を一覧表示するには?
  9. 関連コマンド
  10. 参考
  11. 関連記事

結論:lnコマンドの使い方(最短)

書き方だけ確認したい場合は次の4行で足ります。指定する順番は「実体 → リンク名」で、cpmv と同じ並びです。

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        <- 中に作られてしまった

currentv1 を指したままで、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 : ファイルやシンボリックリンクを削除

参考

Bash玄

はじめまして!Bash玄です。

エンジニアとしてシステム運用に携わる中で、手作業の多さに限界を感じ、Bashスクリプトを活用して業務を効率化したのがきっかけで、この道に入りました。「手作業は負け」「スクリプトはシンプルに」をモットーに、誰でも実践できるBashスクリプトの書き方を発信しています。

このサイトでは、Bashの基礎から実践的なスクリプト作成まで、初心者でもわかりやすく解説しています。少しでも「Bashって便利だな」と思ってもらえたら嬉しいです!

# 好きなこと
- シンプルなコードを書くこと
- コマンドラインを快適にカスタマイズすること
- 自動化で時間を生み出すこと

# このサイトを読んでほしい人
- Bashに興味があるけど、何から始めればいいかわからない人
- 定型業務を自動化したい人
- 効率よくターミナルを使いこなしたい人

Bashの世界に一歩踏み出して、一緒に「Bash道」を極めていきましょう!

Bash玄をフォローする

コメント