Ubuntuでシンボリックリンクを作成するlnコマンドの使い方

コマンド

動作確認環境

本記事のコマンドは Ubuntu 24.04 LTS(Docker公式イメージ ubuntu:24.04)で実際に実行して確認しています。Ubuntu 22.04 でも基本的な使い方は同じです(後述のバージョン比較を参照)。

Ubuntuを使っていると、「同じファイルを別の場所からも参照したい」「設定ファイルを一か所だけ更新したら全ての場所に反映してほしい」という場面がよくあります。そんなときに役立つのがシンボリックリンクです。

結論から言うと、ln -s リンク先 リンク名 で作成できます。ln コマンドは coreutils パッケージに含まれており、Ubuntu 24.04 には最初からインストールされています(実測:coreutils 9.4-3ubuntu6.2)。

本記事では、実際に Ubuntu 24.04 Docker コンテナでコマンドを実行した結果とともに、ソフトリンク(シンボリックリンク)とハードリンクの違い、よく使うオプション、よくあるエラーと対処法まで解説します。

この記事のポイント

  • シンボリックリンクは ln -s リンク先 リンク名 で作成する(coreutils 付属・インストール不要)
  • ls -la でリンク先が → ファイル名 形式で表示される。lrwxrwxrwxl がシンボリックリンクの証
  • ソフトリンクとハードリンクは inode 番号 で見分けられる。ハードリンクは元ファイルと同じ inode になる(実測:Ubuntu 24.04 で確認)
  • 元ファイルを削除するとソフトリンクはリンク切れ(dangling link)になるが、ハードリンクはデータが残る
  • リンクが既に存在するときは -f(force)オプションで強制上書きできる

目次

  1. シンボリックリンクとハードリンクの違い
  2. ln -s でシンボリックリンクを作成する
  3. ハードリンクを作成する(ln)
  4. inode 番号で違いを確認する
  5. 元ファイルを削除したときの挙動の違い
  6. ディレクトリへのシンボリックリンク
  7. readlink でリンク先を確認する
  8. Ubuntu 22.04 vs 24.04 バージョン比較
  9. よくあるエラーと解決策
  10. まとめ

ln コマンドが作れるリンクには「ソフトリンク(シンボリックリンク)」と「ハードリンク」の2種類があります。混乱しやすいポイントなので、最初に整理しておきます。

項目 ソフトリンク(シンボリックリンク) ハードリンク
コマンド ln -s 元ファイル リンク名 ln 元ファイル リンク名
実態 ファイルパスへのショートカット 同じ inode への別名
inode 番号 元ファイルと別(実測:1342743 vs 1342742) 元ファイルと同じ(実測:1342742)
ディレクトリに使える? はい(よく使う) いいえ(不可)
元ファイルを削除すると? リンク切れ(dangling link)になる データはそのまま残る
別パーティションをまたげる? はい いいえ

実際に使う場面では、ほとんどのケースでソフトリンク(ln -sを使います。ディレクトリへのリンクや、別パーティションをまたぐ場合も対応できるからです。ハードリンクは特殊なユースケース(バックアップツールなど)向けです。

①基本的な使い方

書式は次の通りです。




ubuntu@linuxlab: ~
$ ln -s リンク先(実体ファイルのパス) リンク名

実際にやってみましょう。original.txt というファイルを作り、soft_link.txt という名前のシンボリックリンクを作成します。




ubuntu@linuxlab: ~/lntest
$ echo “Hello, LinuxLab!” > original.txt
$ ln -s original.txt soft_link.txt
$ ls -la soft_link.txt
lrwxrwxrwx 1 root root 12 Jun 13 09:37 soft_link.txt -> original.txt

ls -la の出力で確認できる点が2つあります。

  • 先頭の l:ファイル種別が「リンク(link)」であることを示す(通常ファイルは -、ディレクトリは d
  • soft_link.txt -> original.txt:リンク先が矢印で表示される

②リンク経由でファイルを読む

シンボリックリンクは透過的に動作するので、cat コマンドで読むと元ファイルの中身が返ってきます。




ubuntu@linuxlab: ~/lntest
$ cat soft_link.txt
Hello, LinuxLab!
ln コマンドでシンボリックリンクを作成・inode比較(実測)
ln コマンドでシンボリックリンクを作成・inode比較(実測)

正直、この「透過的に動く」という挙動が最初はわかりにくいと思います。シンボリックリンクは Windows でいうショートカット(.lnk ファイル)に近いイメージですが、Linux ではアプリ側がリンクであることを意識せずに普通のファイルと同じように使えます。

ハードリンクは -s オプションをつけずに ln を実行します。




ubuntu@linuxlab: ~/lntest
$ ln original.txt hard_link.txt
$ ls -la hard_link.txt
-rw-r–r– 2 root root 17 Jun 13 09:37 hard_link.txt

ls -la の出力を見ると、先頭が -(通常ファイル)で、パーミッションも元ファイルと同じです。リンク数(2列目の数字)が 2 になっていますが、これは「同じ inode を指しているファイルが2つある」という意味です。

inode 番号で違いを確認する

ソフトリンクとハードリンクの本質的な違いは inode 番号 で見えます。ls -i を使って確認します。




ubuntu@linuxlab: ~/lntest
$ ls -i original.txt soft_link.txt hard_link.txt
1342742 hard_link.txt
1342742 original.txt
1342743 soft_link.txt

Ubuntu 24.04 で実測した結果、hard_link.txtoriginal.txt の inode 番号はどちらも 1342742 で完全に一致しています。一方、soft_link.txt1342743 という別の inode を持っています。

さらに stat コマンドで詳細を確認できます。




ubuntu@linuxlab: ~/lntest
$ stat soft_link.txt
File: soft_link.txt -> original.txt
Size: 12 Blocks: 0 IO Block: 4096 symbolic link
Device: 0,164 Inode: 1342743 Links: 1
Access: (0777/lrwxrwxrwx) Uid: (0/root) Gid: (0/root)
$ stat hard_link.txt
File: hard_link.txt
Size: 17 Blocks: 8 IO Block: 4096 regular file
Device: 0,164 Inode: 1342742 Links: 2
Access: (0644/-rw-r–r–) Uid: (0/root) Gid: (0/root)

ポイントは2つです。

  • soft_link.txt の種別は symbolic link、サイズは 12 バイト(「original.txt」という文字列の長さ)、Blocks は 0
  • hard_link.txt の種別は regular file、Links は 2(同じ inode を参照するファイルが2つ)

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

ここが一番重要な違いです。元ファイル(original.txt)を削除して何が起きるかを実際に確認しました。




ubuntu@linuxlab: ~/lntest
$ rm original.txt
# ソフトリンクはリンク切れになる
$ cat soft_link.txt
cat: soft_link.txt: No such file or directory
# ハードリンクはデータが残る
$ cat hard_link.txt
Hello, LinuxLab!
元ファイルを削除したときの挙動の違い(実測)
元ファイルを削除したときの挙動の違い(実測)

soft_link.txtoriginal.txt へのパスを保持しているだけなので、実体が消えると「リンク切れ(dangling link)」状態になります。一方 hard_link.txt は同じ inode を直接参照しているため、「original.txt」という名前の参照が消えても実データは残ります。

著者アイコン
著者アイコン

ハードリンクはこの挙動から、差分バックアップツール(rsync –link-dest など)で大量ファイルのコピーコストを節約する用途でよく使われます。ただし普段の用途ではほぼソフトリンクで足ります。

ディレクトリへのシンボリックリンクも ln -s で作れます。ハードリンクではディレクトリをリンクしようとするとエラーになりますが(後述)、ソフトリンクなら問題ありません。




ubuntu@linuxlab: ~/lntest2
$ ln -s /tmp/lntest2/dir_a /tmp/lntest2/dir_link
$ ls -la /tmp/lntest2/
drwxr-xr-x 2 root root 4096 Jun 13 09:37 dir_a
drwxr-xr-x 2 root root 4096 Jun 13 09:37 dir_b
lrwxrwxrwx 1 root root 18 Jun 13 09:37 dir_link -> /tmp/lntest2/dir_a
$ ls -la /tmp/lntest2/dir_link/
-rw-r–r– 1 root root 22 Jun 13 09:37 data.txt

dir_link を通じて dir_a 以下のファイルにアクセスできています。たとえば /etc/nginx/sites-enabled/ のような設定ディレクトリへのリンクを作って、環境ごとの設定を切り替えるといった使い方が一般的です。

相対パス vs 絶対パスでリンクを作る

リンク先には絶対パスも相対パスも使えます。相対パスを使う場合、リンク名から見たパスで指定する必要があります。




ubuntu@linuxlab: ~/lntest2/dir_b
# 相対パスでリンク作成(dir_b/ から見て ../dir_a/data.txt)
$ ln -s ../dir_a/data.txt link_relative.txt
$ ls -la link_relative.txt
lrwxrwxrwx 1 root root 17 Jun 13 09:37 link_relative.txt -> ../dir_a/data.txt
# 絶対パスでリンク作成
$ ln -sf /tmp/lntest2/dir_a/data.txt link_absolute.txt
$ ls -la link_absolute.txt
lrwxrwxrwx 1 root root 27 Jun 13 09:37 link_absolute.txt -> /tmp/lntest2/dir_a/data.txt

絶対パスにするとリンクをどこに移動しても動き続けます。相対パスにするとディレクトリごと移動したときにリンクが壊れない利点があります。どちらにするかはユースケース次第です。

シンボリックリンクのリンク先を確認するには readlink コマンドが便利です。




ubuntu@linuxlab: ~/lntest2/dir_b
# 記録されているパス文字列をそのまま返す
$ readlink link_relative.txt
../dir_a/data.txt
# -f で絶対パスに解決して返す
$ readlink -f link_relative.txt
/tmp/lntest2/dir_a/data.txt
$ readlink link_absolute.txt
/tmp/lntest2/dir_a/data.txt
readlink でシンボリックリンク先を確認(実測)
readlink でシンボリックリンク先を確認(実測)

readlink は記録されたパス文字列(相対なら相対)をそのまま返します。-f オプションをつけると正規化された絶対パスを返してくれます。シェルスクリプトでリンクの実体パスを特定したいときは readlink -f が定番です。

Ubuntu 22.04 vs 24.04 バージョン比較

ln コマンドは coreutils パッケージに含まれています。Ubuntu 22.04 と 24.04 で実際にバージョンを確認しました。




ubuntu@linuxlab: ~
# Ubuntu 24.04
$ dpkg -l coreutils | grep ‘^ii’
ii coreutils 9.4-3ubuntu6.2 arm64 GNU core utilities
$ ln –version
ln (GNU coreutils) 9.4
# Ubuntu 22.04
$ dpkg -l coreutils | grep ‘^ii’
ii coreutils 8.32-4.1ubuntu1.3 arm64 GNU core utilities
$ ln –version
ln (GNU coreutils) 8.32
Ubuntu 22.04 vs 24.04 coreutils バージョン比較(実測)
Ubuntu 22.04 vs 24.04 coreutils バージョン比較(実測)

Ubuntu 22.04 では coreutils 8.32、Ubuntu 24.04 では 9.4 が入っています。ただし ln -sln -freadlink など記事で扱うオプションは両バージョンで同一の動作です。

よくあるエラーと解決策

エラー1: File exists(ファイルが既に存在する)

リンク名がすでに存在している状態で ln -s を実行するとエラーになります。




ubuntu@linuxlab: ~
$ ln -s original.txt mylink.txt
$ ln -s original.txt mylink.txt
ln: failed to create symbolic link ‘mylink.txt’: File exists
# 解決策: -f オプションで強制上書き
$ ln -sf original.txt mylink.txt && echo ‘(成功)’
(成功)

-f(force)オプションを付けると既存のリンクを上書きします。スクリプトで繰り返し実行する場合は ln -sf を使うのが定番です。

エラー2: hard link not allowed for directory(ディレクトリのハードリンク)




ubuntu@linuxlab: ~
$ ln /tmp/mydir /tmp/mydir_hardlink
ln: /tmp/mydir: hard link not allowed for directory
# ディレクトリをリンクしたいときはソフトリンクを使う
$ ln -s /tmp/mydir /tmp/mydir_link
(エラーなし)

ディレクトリへのリンクが必要なときは ln -s を使います。

エラー3: リンク切れ(dangling link)

存在しないファイルへのシンボリックリンクも作れてしまいます(これは仕様)。後からリンク先のファイルが作られれば有効になります。




ubuntu@linuxlab: ~
$ ln -s nonexistent.txt dangling_link.txt
lrwxrwxrwx 1 root root 15 Jun 13 09:37 dangling_link.txt -> nonexistent.txt
$ cat dangling_link.txt
cat: dangling_link.txt: No such file or directory

リンク切れの調査には find -L . -type l ! -xtype l(全リンク切れを検出)や、ls -la の色付き表示(端末によってリンク切れが赤表示になる)が便利です。

よくあるエラーと解決策(実測)
よくあるエラーと解決策(実測)

-v オプションで操作内容を確認する

どんなリンクが作られたか確認しながら進めたいときは -v(verbose)オプションが便利です。




ubuntu@linuxlab: ~
$ ln -sv original.txt verbose_link.txt
‘verbose_link.txt’ -> ‘original.txt’

まとめ

本記事で確認した ln コマンドのポイントをまとめます。

  • ln -s リンク先 リンク名 でソフトリンク(シンボリックリンク)を作成する
  • ln リンク先 リンク名(-s なし)でハードリンクを作成する
  • ls -la の先頭 l と矢印表示でシンボリックリンクと分かる
  • ls -i の inode 番号:ハードリンクは元ファイルと同一、ソフトリンクは別(Ubuntu 24.04 で実測)
  • 元ファイルを削除するとソフトリンクはリンク切れ(dangling link)になる。ハードリンクはデータが残る
  • 同名リンクが既に存在するときは -f で強制上書き。ディレクトリへのリンクは ln -s のみ
  • readlink -f リンク名 でリンクの絶対パスを調べられる
  • Ubuntu 22.04(coreutils 8.32)→ Ubuntu 24.04(coreutils 9.4)でバージョンアップしているが、基本的な使い方に変更なし

Linux のファイル操作をもっと深く学びたい方は、VPS を借りて実際にサーバー環境を構築するのが一番の近道です。学習用として月 $5 〜 $6 から使える VPS サービスも紹介していますので、参考にしてみてください。

コメント

タイトルとURLをコピーしました