ハードリンクとシンボリックリンクの挙動と使い道
リンクについてまとめていく。
コマンドの結果はmacOS Monterey 12.0.1
での実行結果です。
リンクとは
リンクとは異なるパスで同じファイルやディレクトリにアクセスできるようにする仕組み。 Unixのリンクはハードリンクとシンボリックリンクの大きく2つの種類がある。
ハードリンクはln
コマンド、シンボリックリンクはln
コマンドにs
オプションを付けて以下のように作成する。
$ ln -s <リンク元のパス> <リンクを張るパス>
ハードリンクはファイルにのみリンクを張ることができるが、シンボリックリンクはディレクトリにもリンクを貼ることができる。
ハードリンクとシンボリックリンクについて
ハードリンクについて
ハードリンクとは、広義には「あるinodeとそのファイルに付けれた名前との繋がり」のこと。 つまり「ハードリンクを張る」というのは同じinodeを参照する別名のファイルを作成するということである。
同じinodeを参照するのでファイルサイズなどのメタデータも同じで、参照しているデータブロックも同じ。
例えばこんなファイルを作成する。
❯ cat ~/Desktop/etc/hard-link-source.conf The file for hard link.
lsコマンドでinode番号などを確認すると
❯ ls -li ~/Desktop/etc/hard-link-source.conf 45031490 -rw-r--r-- 1 user-name staff 59 2 12 15:18 /Users/user-name/Desktop/etc/hard-link-source.conf
ハードリンクを/etc/
にhard.conf
という名前で張る。
sudo ln ~/Desktop/etc/hard-link-source.conf /etc/hard-link.conf
lsコマンドでハードリンクを確認してみる。
❯ ls -li /etc/hard-link.conf 45031490 -rw-r--r-- 2 user-name staff 59 2 12 15:18 /etc/hard-link.conf
このように同じinode番号を持った別名のファイルができている。
先ほども説明したように、同じinode番号を持っているので同じinodeを参照しており、参照しているデータブロックも同じなため実データも同じである。
片方でファイルを編集すると、もう片方からファイル内容を確認しても変更が反映されている。
例えば~/Desktop/etc/hard-link-source.conf
からファイルを編集して、/etc/hard-link.conf
を確認すると
❯ cat /etc/hard-link.conf The file for hard link. New line by hard-link-source.conf.
ハードリンクは同じinode番号を持った別名のファイルを作るので、どちらが親でどちらが子かなどの主従関係はない。
シンボリックリンクについて
シンボリックリンクを張ると、別のinode番号を持つファイルを作成する。
ファイルの実体はリンク元のファイルパスだが、そのファイルパスを参照するのでcat
コマンドなどでファイル内容を確認すると、リンク元のファイル内容と同じものが確認できる。
ファイルの実態はリンク元のファイルパスなのでファイル容量は非常に小さい。
以下のファイルを作成する。
❯ cat ~/Desktop/etc/symbolic-link-source.conf The file for symbolic link.
❯ ls -li ~/Desktop/etc/symbolic-link-source.conf 45029769 -rw-r--r-- 1 user-name staff 28 2 12 14:44 /Users/user-name/Desktop/etc/symbolic-link-source.conf
リンクを貼る。
❯ sudo ln -s ~/Desktop/etc/symbolic-link-source.conf /etc/symbolic-link.conf
❯ ls -li /etc/symbolic-link.conf 45029868 lrwxr-xr-x 1 root wheel 59 2 12 14:46 /etc/symbolic-link.conf -> /Users/user-name/Desktop/etc/symbolic-link-source.conf
このようにinode番号は異なる。 ハードリンクと同じように片方のファイルから変更を加えてももう片方から変更を確認することができる。
今度は/etc/symbolic-link.conf
から変更を加えて、~/Desktop/etc/symbolic-link-source.conf
を確認してみる。
❯ cat ~/Desktop/etc/symbolic-link-source.conf The file for symbolic link. New line by symbolic-link.conf.
その他の違い
削除時
移動時
その他
それぞれの用途
ハードリンクを利用している「.
」「..
」の仕組み
前述したようにディレクトリのハードリンクを張ることは基本的にできない。
しかしコンピューター内部の処理ではディレクトリのハードリンクが使われている。
カレントディレクトリを表す「.
」や1つ上のディレクトリを表す「..
」はディレクトリへのハードリンクである。
これらのハードリンクはディレクトリ作成時に作成される。
ディレクトリを作成して確認してみる。
❯ mkdir ~/test
作成したtest
というディレクトリの情報を確認してみる。
❯ ls -lid ~/test 45027781 drwxr-xr-x 2 user-name staff 64 2 12 13:53 /Users/user-name/test
user-nameの前の数字はハードリンクの数で、test
ディレクトリへのハードリンクの数は2
となっている。
つまり、test
ディレクトリをリンク元にしているハードリンクが2つあるということになる。
そもそもハードリンクとは、あるファイルのinodeとそのファイルにつけられた名前との繋がりのことなので、普通にファイルを作成するとそのファイルはハードリンクを1つ持つ。
ディレクトリの実体は、ディレクトリ配下のファイルのinode番号とファイル名のリストを格納したファイルなので、ディレクトリ自体がハードリンクとしてカウントされる。
もう1つ目はカレンとディレクトリ「.
」である。
❯ ls -lia ~/test total 0 45027781 drwxr-xr-x 2 user-name staff 64 2 12 13:53 . 362921 drwxr-xr-x+ 87 user-name staff 2784 2 12 15:18 ..
このようにディレクトリ作成によってカレントディレクトリ「.
」と1つ上のディレクトリ「..」が作成されている。
カレントディレクトリ「.
」のinode番号はtest
ディレクトリと同じになっていて、ハードリンクなのが分かる。
このようにディレクトリ作成時にはディレクトリそのものとカレントディレクトリ「.
」の2つによってハードリンクが2つカウントされる。
ちなみに同じくディレクトリ作成によって作成される1つ上のディレクトリ「..」は作成したディレクトリの1つ上のディレクトリへのハードリンクになっているので、test
ディレクトリの1つ上のディレクトリである~
のinode番号と同じになっている。
❯ ls -lid ~ 362921 drwxr-xr-x+ 87 user-name staff 2784 2 12 15:18 /Users/user-name
シンボリックの利用用途
例えば階層の違うファイルをGit管理したいときに使う。
元々Git管理されているのは~/service-name
だとして、設定ファイルは階層の違うディレクトリ/etc/hoge.conf
にあるとする。
/etc/hoge.conf
をGit管理下に置くには、まずGit管理下に設定ファイルをコピーする。
❯ cp /etc/hoge.conf ~/service-name/hoge.conf
コピーした内容を一旦コミットする。
次に元々あったファイルを削除してシンボリックリンクを張る。(conf
を参照しているサービス(Nginxとか)は再起動しないといけなそう)
❯ sudo rm /etc/hoge.conf ❯ sudo ln -s ~/service-name/hoge.conf /etc/hoge.conf