こちらからSWELLを購入できます 詳しくはこちら

【Linux】lnコマンド完全ガイド シンボリックリンクを作成する

  • URLをコピーしました!

今回はLinuxコマンドであるlnコマンドについて解説します

lnコマンドは、ファイルやディレクトリに別の名前(リンク)を付けるコマンドで、ハードリンクとシンボリックリンクの2種類を作れます
アプリのバージョン切り替えや設定ファイルの差し替えなど、サーバー運用の現場でよく使うコマンドなので、ぜひ覚えて帰ってくださいね!
※注 本文の△は半角スペースに置き換えてください。わかりやすくするために△で記述してます

スポンサーリンク
目次

lnコマンドとは??

lnコマンドは、ファイルやディレクトリへのリンクを作るコマンドです
名前は「link(リンク)」の略です
オプションなしで実行するとハードリンク、-sオプションを付けるとシンボリックリンクを作ります
ハードリンクは「同じファイルの実体にもう1つ名前を付けたもの」、シンボリックリンクは「別のファイルの場所(パス)を書いた案内板のようなもの」です
Windowsのショートカットに近いのはシンボリックリンクのほうで、実務ではシンボリックリンクを使う場面がほとんどです
この記事の実行結果は、GNU coreutils 9.4のln(Ubuntu 24.04)を一般ユーザー(user)で実行して確認しています

lnコマンドの主なオプション

lnコマンドの主なオプションは次のとおりです

オプション意味
-s (–symbolic)ハードリンクではなく、シンボリックリンクを作るオプション
-f (–force)作ろうとしたリンク名のファイルがすでにあるとき、それを削除してからリンクを作るオプション
-n (–no-dereference)リンク名がディレクトリへのシンボリックリンクだったとき、その中に入らず、リンク自体を普通のファイルとして扱うオプション
-i (–interactive)リンク名のファイルがすでにあるとき、置き換えてよいか確認してくれるオプション
-v (–verbose)作ったリンクを1つずつ表示するオプション
-r (–relative)-sと一緒に使い、リンクを置く場所から見た相対パスでシンボリックリンクを作るオプション
-b (–backup)リンク名のファイルがすでにあるとき、置き換える前のファイルをバックアップとして残すオプション

ここからは、テスト用のディレクトリln-testの中に練習用ファイルを作って説明します
次のコマンドで同じファイルを作れるので、一緒に試してみてください

事前準備(テスト用ディレクトリの作成)
mkdir△ln-test
cd△ln-test
printf△”hello△ln\n”△>△memo.txt
mkdir△docs△app-1.2△app-1.3△conf
printf△”manual△v1\n”△>△docs/manual.txt
printf△”version=1.2\n”△>△app-1.2/version.txt
printf△”version=1.3\n”△>△app-1.3/version.txt
printf△”env=dev\nport=8080\n”△>△conf/app-dev.conf
printf△”env=prod\nport=80\n”△>△conf/app-prod.conf
touch△-d△”2026-11-01△10:00″△memo.txt△docs△docs/manual.txt△app-1.2△app-1.2/version.txt△app-1.3△app-1.3/version.txt△conf△conf/app-dev.conf△conf/app-prod.conf
# 作成したディレクトリの構成を確認する
ls△-lR
実行結果:
.:
total 20
drwxrwxr-x 2 user user 4096 Nov 1 10:00 app-1.2
drwxrwxr-x 2 user user 4096 Nov 1 10:00 app-1.3
drwxrwxr-x 2 user user 4096 Nov 1 10:00 conf
drwxrwxr-x 2 user user 4096 Nov 1 10:00 docs
-rw-rw-r– 1 user user 9 Nov 1 10:00 memo.txt

./app-1.2:
total 4
-rw-rw-r– 1 user user 12 Nov 1 10:00 version.txt

./app-1.3:
total 4
-rw-rw-r– 1 user user 12 Nov 1 10:00 version.txt

./conf:
total 8
-rw-rw-r– 1 user user 18 Nov 1 10:00 app-dev.conf
-rw-rw-r– 1 user user 17 Nov 1 10:00 app-prod.conf

./docs:
total 4
-rw-rw-r– 1 user user 10 Nov 1 10:00 manual.txt

# ファイルの中身を確認する
cat△memo.txt
実行結果:
hello ln
cat△docs/manual.txt
実行結果:
manual v1
cat△app-1.2/version.txt△app-1.3/version.txt
実行結果:
version=1.2
version=1.3
cat△conf/app-dev.conf
実行結果:
env=dev
port=8080
cat△conf/app-prod.conf
実行結果:
env=prod
port=80

以降のコマンドは、すべてln-testの中で実行します
シンボリックリンクを作った後に実行している「touch△-h△-d△”2026-11-01△10:00″△リンク名」は、この記事の実行結果の日時をそろえるためのものなので、普段は必要ありません(-hを付けると、リンク先ではなくリンク自体の日時を変えられます)

-s (–symbolic)

ハードリンクではなく、シンボリックリンクを作るオプションです
ls△-lで見ると、先頭が「l」になり、「リンク名△->△リンク先」の形で表示されます

コマンド実行例
ln△-s△memo.txt△memo-link.txt
touch△-h△-d△”2026-11-01△10:00″△memo-link.txt
ls△-l△memo.txt△memo-link.txt
実行結果:
lrwxrwxrwx 1 user user 8 Nov 1 10:00 memo-link.txt -> memo.txt
-rw-rw-r– 1 user user 9 Nov 1 10:00 memo.txt
# memo-link.txtがmemo.txtを指すシンボリックリンクになっています

# リンクを通して中身を読む
cat△memo-link.txt
実行結果:
hello ln
# リンク先のmemo.txtの中身が表示されます

-f (–force)

作ろうとしたリンク名のファイルがすでにあるとき、それを削除してからリンクを作るオプションです
-fなしだと「File exists」のエラーになり、リンクは作られません

コマンド実行例
# -fなしで、すでにある名前でリンクを作ろうとする
LC_ALL=C△ln△-s△docs/manual.txt△memo-link.txt
実行結果:
ln: failed to create symbolic link ‘memo-link.txt’: File exists
# すでにmemo-link.txtがあるのでエラーになります

# -fありで、リンク先を張り替える
ln△-sf△docs/manual.txt△memo-link.txt
readlink△memo-link.txt
実行結果:
docs/manual.txt
# リンク先がdocs/manual.txtに変わりました(readlinkはリンク先を表示するコマンドです)

# リンク先をmemo.txtに戻す
ln△-sf△memo.txt△memo-link.txt
# -fはリンク名に普通のファイルがあっても消してしまうので、名前を間違えないよう注意してください

-n (–no-dereference)

リンク名がディレクトリへのシンボリックリンクだったとき、その中に入らず、リンク自体を普通のファイルとして扱うオプションです
ディレクトリへのリンクを-sfで張り替えるときは、-nも付けて「-sfn」にするのが定番です

コマンド実行例
# 事前準備:app-1.2を指すリンクlatestを作る
ln△-s△app-1.2△latest

# -nなしで、リンク先をapp-1.3に張り替えようとする
ln△-sf△app-1.3△latest
readlink△latest
実行結果:
app-1.2
# リンク先はapp-1.2のまま変わっていません
ls△app-1.2
実行結果:
app-1.3 version.txt
# latestがapp-1.2の中に入ってしまい、app-1.2の中にapp-1.3というリンクが作られています

# 間違って作られたリンクを削除する
rm△app-1.2/app-1.3

# -nありで張り替える
ln△-sfn△app-1.3△latest
readlink△latest
実行結果:
app-1.3
# 今度はlatest自体が張り替わりました

# 練習用のリンクを削除する
rm△latest

-i (–interactive)

リンク名のファイルがすでにあるとき、置き換えてよいか確認してくれるオプションです
「y」と入力すると置き換え、「n」と入力すると何もせずに終了します

コマンド実行例
ln△-si△docs/manual.txt△memo-link.txt
実行結果:
ln: replace ‘memo-link.txt’? n
# 確認が表示されるので、nを入力してEnterを押しています
readlink△memo-link.txt
実行結果:
memo.txt
# 置き換えなかったので、リンク先はmemo.txtのままです

-v (–verbose)

作ったリンクを1つずつ表示するオプションです
シンボリックリンクは「->」、ハードリンクは「=>」で表示されるので、どちらを作ったのか確認できます

コマンド実行例
ln△-sv△memo.txt△memo-link2.txt
実行結果:
‘memo-link2.txt’ -> ‘memo.txt’
ln△-v△memo.txt△memo-hard2.txt
実行結果:
‘memo-hard2.txt’ => ‘memo.txt’

# 練習用のリンクを削除する
rm△memo-link2.txt△memo-hard2.txt

-r (–relative)

-sと一緒に使い、リンクを置く場所から見た相対パスでシンボリックリンクを作るオプションです
GNU版のlnのオプションで、ほかの実装では使えない場合があります

コマンド実行例
# 事前準備:リンクを置くディレクトリを作る
mkdir△links

# -rなしで、別のディレクトリにリンクを作る
ln△-s△docs/manual.txt△links/manual-ng.txt
readlink△links/manual-ng.txt
実行結果:
docs/manual.txt
LC_ALL=C△cat△links/manual-ng.txt
実行結果:
cat: links/manual-ng.txt: No such file or directory
# 相対パスはリンクを置いた場所(links)から見て解釈されるので、links/docs/manual.txtを探してしまい読めません

# -rありで作る
ln△-sr△docs/manual.txt△links/manual-ok.txt
readlink△links/manual-ok.txt
実行結果:
../docs/manual.txt
cat△links/manual-ok.txt
実行結果:
manual v1
# linksから見た正しい相対パス(../docs/manual.txt)に変換してくれます

# 練習用のディレクトリを削除する
rm△-r△links

-b (–backup)

リンク名のファイルがすでにあるとき、置き換える前のファイルをバックアップとして残すオプションです
バックアップは、名前の最後に「~」が付いたファイルになります(-S (–suffix)で付ける文字を変えられます)

コマンド実行例
ln△-sb△docs/manual.txt△memo-link.txt
ls△memo-link.txt*
実行結果:
memo-link.txt memo-link.txt~
readlink△memo-link.txt△memo-link.txt~
実行結果:
docs/manual.txt
memo.txt
# 新しいリンクはdocs/manual.txtを指し、元のリンクはmemo-link.txt~として残っています

# バックアップを元の名前に戻す
mv△memo-link.txt~△memo-link.txt
readlink△memo-link.txt
実行結果:
memo.txt

基本的な使い方

lnコマンドの基本的な構文は「ln△オプション△リンク元(本物のファイル)△リンク名」です
cpコマンドと同じく「元→新しい名前」の順番で書くと覚えておきましょう
リンク名にディレクトリを指定すると、そのディレクトリの中に同じ名前でリンクが作られます

コマンド実行例
# ハードリンクを作る
ln△memo.txt△memo-hard.txt

# シンボリックリンクを作る
ln△-s△memo.txt△memo-sym.txt
touch△-h△-d△”2026-11-01△10:00″△memo-sym.txt

# 作ったリンクを確認する
ls△-l△memo.txt△memo-hard.txt△memo-sym.txt
実行結果:
-rw-rw-r– 2 user user 9 Nov 1 10:00 memo-hard.txt
lrwxrwxrwx 1 user user 8 Nov 1 10:00 memo-sym.txt -> memo.txt
-rw-rw-r– 2 user user 9 Nov 1 10:00 memo.txt
# ハードリンクは普通のファイルと見た目が同じで、2列目の数字(リンク数)が2になっています

ハードリンクとシンボリックリンクの違い

2つのリンクの違いを、実際に動かして確認してみましょう

inode番号とリンク数

Linuxのファイルは、中身や権限などの情報を「inode」という管理番号で管理していて、ファイル名はinodeに付けた名前にすぎません
ハードリンクは同じinodeに名前をもう1つ付けたもの、シンボリックリンクは別のinodeを持つ小さなファイルです
ls△-liで、先頭にinode番号を表示して確認できます(inode番号は環境や実行のたびに違う値になります)

inode番号の確認
ls△-li△memo.txt△memo-hard.txt△memo-sym.txt
実行結果:
795130 -rw-rw-r– 2 user user 9 Nov 1 10:00 memo-hard.txt
795378 lrwxrwxrwx 1 user user 8 Nov 1 10:00 memo-sym.txt -> memo.txt
795130 -rw-rw-r– 2 user user 9 Nov 1 10:00 memo.txt
# memo.txtとmemo-hard.txtは同じinode番号で、memo-sym.txtだけ違う番号になっています
# 同じ実体なので、どちらの名前で書き換えても、もう一方の中身も同じように変わります

元のファイルを削除したときの違い

元のファイルを削除すると、ハードリンクは中身を読めたままですが、シンボリックリンクはリンク切れ(壊れたリンク)になります
ハードリンクは、リンク数が0になったときに初めて中身が消えるためです

元のファイルを削除する例
rm△memo.txt
ls△-l△memo-hard.txt△memo-sym.txt
実行結果:
-rw-rw-r– 1 user user 9 Nov 1 10:00 memo-hard.txt
lrwxrwxrwx 1 user user 8 Nov 1 10:00 memo-sym.txt -> memo.txt
# memo-hard.txtのリンク数が1に減り、memo-sym.txtは存在しないmemo.txtを指したままです
# 色付きで表示する設定の端末では、リンク切れのmemo-sym.txtが赤く表示されます

cat△memo-hard.txt
実行結果:
hello ln
LC_ALL=C△cat△memo-sym.txt
実行結果:
cat: memo-sym.txt: No such file or directory
# ハードリンクは読めますが、シンボリックリンクはリンク先がないのでエラーになります

# 元に戻す(同じ名前のファイルができれば、シンボリックリンクも直る)
mv△memo-hard.txt△memo.txt
cat△memo-sym.txt
実行結果:
hello ln

# 練習用のリンクを削除する
rm△memo-sym.txt

違いのまとめ

ハードリンク:同じinodeを共有する/元を消しても読める/ディレクトリには作れない/別のファイルシステム(パーティション)をまたげない
シンボリックリンク:パスを書いた別のファイル/元を消すとリンク切れになる/ディレクトリにも作れる/別のファイルシステムにも作れる

readlinkでリンク先を確認する

readlinkはシンボリックリンクに書かれたリンク先をそのまま表示し、-fを付けるとリンクを最後までたどった絶対パスを表示します
リンクのリンク(多段のリンク)の最終的な行き先を知りたいときは、readlink△-fが便利です

readlinkの例
# 事前準備:リンクを指すリンクを作る
ln△-s△memo-link.txt△memo-link-link.txt

readlink△memo-link-link.txt
実行結果:
memo-link.txt
# 1段分のリンク先(memo-link.txt)だけが表示されます
readlink△-f△memo-link-link.txt
実行結果:
/home/user/ln-test/memo.txt
# 最後までたどった本物のファイルの絶対パスが表示されます
# /home/user/ln-testの部分は、実行した環境のパスになります

# 練習用のリンクを削除する
rm△memo-link-link.txt

相対パスと絶対パスのシンボリックリンク

シンボリックリンクのリンク先は、相対パスでも絶対パスでも書けます
相対パスは「リンクを置いた場所」から見て解釈されるので、リンクだけを別の場所に移すとリンク切れになります
絶対パスはリンクを移動しても切れませんが、リンク先のディレクトリごと移動・名前変更すると切れます

相対パスと絶対パスの例
pwd
実行結果:
/home/user/ln-test

# 相対パスと絶対パスでリンクを作る($PWDは今いるディレクトリのパスに置き換わる)
ln△-s△docs/manual.txt△rel-manual.txt
ln△-s△”$PWD/docs/manual.txt”△abs-manual.txt
touch△-h△-d△”2026-11-01△10:00″△rel-manual.txt△abs-manual.txt
ls△-l△rel-manual.txt△abs-manual.txt
実行結果:
lrwxrwxrwx 1 user user 34 Nov 1 10:00 abs-manual.txt -> /home/user/ln-test/docs/manual.txt
lrwxrwxrwx 1 user user 15 Nov 1 10:00 rel-manual.txt -> docs/manual.txt
# シンボリックリンクのサイズ(34や15)は、リンク先のパスの文字数です
# 絶対パスの/home/user/ln-testの部分とabs-manual.txtのサイズは、実行した環境によって変わります

# リンクだけを別のディレクトリに移動する
mkdir△moved
mv△rel-manual.txt△abs-manual.txt△moved/
LC_ALL=C△cat△moved/rel-manual.txt
実行結果:
cat: moved/rel-manual.txt: No such file or directory
cat△moved/abs-manual.txt
実行結果:
manual v1
# 相対パスのリンクは切れ、絶対パスのリンクは読めます

# 練習用のディレクトリを削除する
rm△-r△moved

ディレクトリへのシンボリックリンク

シンボリックリンクはディレクトリにも作れて、深い階層のディレクトリへの近道としてよく使います
ls△-lでリンク名だけを指定するとリンク自体の情報が、最後に/を付けるとリンク先のディレクトリの中身が表示されます

ディレクトリへのリンクの例
ln△-s△docs△docs-link
touch△-h△-d△”2026-11-01△10:00″△docs-link
ls△-l△docs-link
実行結果:
lrwxrwxrwx 1 user user 4 Nov 1 10:00 docs-link -> docs
ls△-l△docs-link/
実行結果:
total 4
-rw-rw-r– 1 user user 10 Nov 1 10:00 manual.txt

# リンクを通ってディレクトリに移動する
cd△docs-link
pwd
実行結果:
/home/user/ln-test/docs-link
pwd△-P
実行結果:
/home/user/ln-test/docs
# pwdはリンクの名前のまま、pwd -Pは本当の場所(docs)を表示します
cd△..

# ディレクトリへのリンクを削除する(最後に/を付けない)
rm△docs-link
ls△docs
実行結果:
manual.txt
# リンクだけが消え、リンク先のdocsの中身は残っています

ハードリンクを作れないケース

ハードリンクは、ディレクトリに対しては作れません(ディレクトリの構造が壊れるのを防ぐため)
また、inodeはファイルシステムごとの番号なので、別のファイルシステム(パーティション)をまたいでハードリンクは作れません
どちらの場合も、シンボリックリンクなら作れます

ハードリンクのエラー例
# ディレクトリにハードリンクを作ろうとする
LC_ALL=C△ln△docs△docs-hard
実行結果:
ln: docs: hard link not allowed for directory

# 別のファイルシステム(/dev/shm)にハードリンクを作ろうとする
LC_ALL=C△ln△memo.txt△/dev/shm/ln-test-memo.txt
実行結果:
ln: failed to create hard link ‘/dev/shm/ln-test-memo.txt’ => ‘memo.txt’: Invalid cross-device link
# 多くのLinuxでは/dev/shmはメモリ上の別のファイルシステム(tmpfs)なので、このエラーになります
# 同じファイルシステムの環境でリンクができてしまった場合は、rm /dev/shm/ln-test-memo.txtで削除してください

lnコマンドの実践的な活用例

実際の現場でよく使われるlnコマンドの活用例をご紹介します

アプリのバージョンを切り替える

「current」のような決まった名前のリンクを作り、リンク先のバージョンだけを張り替える運用です
アプリや設定はいつもcurrentを参照するようにしておけば、リンクの張り替えだけでバージョンアップや切り戻しができます

バージョン切り替えの例
# currentをapp-1.2に向ける
ln△-sfnv△app-1.2△current
実行結果:
‘current’ -> ‘app-1.2’
cat△current/version.txt
実行結果:
version=1.2

# app-1.3にバージョンアップする
ln△-sfnv△app-1.3△current
実行結果:
‘current’ -> ‘app-1.3’
cat△current/version.txt
実行結果:
version=1.3

# 問題があればapp-1.2に切り戻す
ln△-sfnv△app-1.2△current
実行結果:
‘current’ -> ‘app-1.2’
cat△current/version.txt
実行結果:
version=1.2
# ディレクトリへのリンクなので、-nを忘れないようにしましょう

設定ファイルを差し替える

環境ごとの設定ファイルを用意しておき、決まった名前のリンクで使う設定を切り替える方法です
どの設定を使っているかは、readlinkやls△-lですぐに確認できます

設定ファイルの差し替えの例
ln△-sfv△conf/app-dev.conf△app.conf
実行結果:
‘app.conf’ -> ‘conf/app-dev.conf’
cat△app.conf
実行結果:
env=dev
port=8080

# 本番用の設定に切り替える
ln△-sfv△conf/app-prod.conf△app.conf
実行結果:
‘app.conf’ -> ‘conf/app-prod.conf’
cat△app.conf
実行結果:
env=prod
port=80
readlink△app.conf
実行結果:
conf/app-prod.conf

findでリンクやリンク切れを探す

find△-type△lでシンボリックリンクを一覧できます
-Lを付けるとリンクをたどって調べるので、たどれない(リンク切れの)リンクだけが「-type△l」に当てはまります
ハードリンクは見た目では区別できないので、-samefileで同じinodeのファイルを探します(-samefileはGNU版のfindのオプションです)

findでリンクを探す例
# 事前準備:リンク切れのリンクを作る
ln△-s△no-such-file.txt△broken.txt

# シンボリックリンクを一覧する
find△.△-type△l△|△sort
実行結果:
./app.conf
./broken.txt
./current
./memo-link.txt

# リンク切れのリンクだけを探す
find△-L△.△-type△l
実行結果:
./broken.txt

# 事前準備:ハードリンクを作る
ln△memo.txt△memo-hard.txt

# memo.txtと同じ実体(inode)のファイルを探す
find△.△-samefile△memo.txt△|△sort
実行結果:
./memo-hard.txt
./memo.txt

# 練習用のリンクを削除する
rm△broken.txt△memo-hard.txt

トラブルシューティング

lnコマンドを使うときによくあるつまずきと、その解決方法です

引数の順番を逆にしてしまう

lnは「ln△-s△本物△リンク名」の順番です
逆に書くと、すでにある本物のファイル名でリンクを作ろうとして「File exists」のエラーになります
このときに-fを付けて実行すると、本物のファイルが消されてリンクに置き換わってしまうので、エラーが出たらまず順番を確認しましょう

順番を逆にした例
LC_ALL=C△ln△-s△memo-new.txt△memo.txt
実行結果:
ln: failed to create symbolic link ‘memo.txt’: File exists
# memo.txtがすでにあるので、エラーで止まってくれます

「Too many levels of symbolic links」エラーが出る

シンボリックリンクがお互いを指していて、ぐるぐる回ってしまう(ループしている)ときのエラーです
readlinkで1段ずつリンク先を確認して、ループしている部分を張り直しましょう

リンクのループの例
ln△-s△loop-b△loop-a
ln△-s△loop-a△loop-b
LC_ALL=C△cat△loop-a
実行結果:
cat: loop-a: Too many levels of symbolic links
readlink△loop-a△loop-b
実行結果:
loop-b
loop-a
# loop-aとloop-bがお互いを指しています

# 練習用のリンクを削除する
rm△loop-a△loop-b

リンクを消したつもりが、リンク先の中身が消えた

ディレクトリへのリンクを「rm△-r△リンク名/」のように最後に/を付けて削除すると、リンクではなくリンク先のディレクトリの中身が削除されます
リンクを消すときは、/を付けずに「rm△リンク名」または「unlink△リンク名」で消しましょう

末尾の/で中身が消える例
# 注意:リンク先の中身が削除されるので、必ず練習用のディレクトリで試してください
# 事前準備:練習用のディレクトリとリンクを作る
mkdir△trash-dir
touch△trash-dir/a.txt△trash-dir/b.txt
ln△-s△trash-dir△trash-link

# 最後に/を付けて削除してしまう
LC_ALL=C△rm△-r△trash-link/
実行結果:
rm: cannot remove ‘trash-link/’: Not a directory
find△trash-dir
実行結果:
trash-dir
# リンクは消えずにエラーになり、リンク先の中にあったa.txtとb.txtが消えてしまいました

# リンクは/を付けずに削除する
unlink△trash-link
rmdir△trash-dir

まとめ

いかがでしたでしょうか
今回はlnコマンドについてまとめてみました
lnはオプションなしでハードリンク、-sでシンボリックリンクを作るコマンドで、書く順番は「ln△-s△本物△リンク名」です
シンボリックリンクはディレクトリや別のファイルシステムにも作れますが、元を消すとリンク切れになるので、readlinkやfind△-L△.△-type△lで確認しましょう
ディレクトリへのリンクの張り替えは「ln△-sfn」、削除は最後に/を付けずに「rm△リンク名」がポイントです
ぜひマスターしてください!

スポンサーリンク

この記事が気に入ったら
いいね または フォローしてね!

よかったらシェアしてね!