UNIX/Linuxの部屋 コマンド:ln

TOP UNIX/Linuxの部屋 UNIX/Linuxコマンド一覧 用語集 新版 由来/読み方辞書 環境変数マニュアル Cシェル変数 システム設定ファイル システムコール・ライブラリ ネットワークプログラミングの基礎知識 クラウドサービス徹底比較・徹底解説




コマンド ln シンボリックリンク・ハードリンクを張る。] このエントリーをはてなブックマークに追加

最終更新


UNIX/Linux の ln コマンドは、ファイルやディレクトリに対して、シンボリックリンクやハードリンクを張るためのコマンドである。「リンクを張る」とはファイル・ディレクトリの別名を作るようなもので、ファイル・ディレクトリを別の名前で参照することができる。リンクにはハードリンクとシンボリックリンクがあり、それぞれの利点があるが、一般的にはシンボリックリンクを使う方がよいだろう。


ln コマンドの基本的な使い方
ハードリンクの場合:
% ln source.txt new.txt
⇒ source.txt に対し、ハードリンクで new.txt を作成する。
シンボリックリンクの場合:
% ln -s source.txt symlink.txt
⇒ source.txt に対し、シンボリックリンク symlink.txt を作成する。
% ln -s /foo/bar/source.txt symlink.txt
⇒ /foo/bar/source.txt に対し、シンボリックリンク symlink.txt を作成する。symlink.txt のみを別のディレクトリに移動しても有効である。
% ln -s ../source.txt symlink.txt
⇒ ../source.txt に対し、シンボリックリンク symlink.txt を作成する。
% ln -s /foo/bar/source.txt
% ln -s ../source.txt
⇒ シンボリックリンク名が同名でよい場合、リンク先のファイルのみを渡してもよい

ハードリンクの作成
ハードリンクとは「ファイル名の複製」と考えるとよい。「ファイルの複製」ではない。
一度ハードリンクを作成すると、「参照先」「参照元」「実体」といった区別はなくなってしまう。

下記のようにすることで、file-a と同じ内容を持つ file-b というファイルを作成することができる。これを「ハードリンクを作成する」と呼ぶ。
% ln file-a file-b
このとき file-a は実際に存在していなくてはならず、新たに作成される file-b が既に存在していてはいけない。一度ハードリンクを張ってしまうと、本当のファイル/別名のファイルという区別はなくなる。これは、file-a と file-b が同じ i-node を指すようになっているからである。

ハードリンクと i-node の関係について ls -li で確かめてみよう。ls に -i オプションを付けることで i-node の情報を表示することができる。
% ls -li file-a
414820 -rw-r--r-- 1 user group 10 Aug 4 14:49 file-a
現在は file-a が存在し、i-node は 414820 である。なお、i-node とは、ファイル・ディレクトリに付けられた一意な番号である。ファイル・ディレクトリ識別番号とでも考えればいいだろう。

file-a のハードリンク file-b を作成する。
% ln file-a file-b
もう一度 ls -li を実行してみよう。
% ls -li file-a file-b
414820 -rw-r--r-- 2 user group 10 Aug 4 14:49 file-a
414820 -rw-r--r-- 2 user group 10 Aug 4 14:49 file-b
file-a と file-b の i-node が同じなのに注目してほしい。i-node が同じということは、file-a と file-b は全く違いがないということである。

file-a の内容を書き換えようとすると、OS は file-a の i-node が 414820 であることを調べ、ディスク中の 414820 に対応するデータが書き換えられる。

同様に file-b を中身を表示しようとした場合も、OS が file-b の i-node が 414820 であることを調べ、ディスク中の 414820 に対応するファイルの中身を表示する。

つまり、file-a を書き換えても file-b を書き換えても、同じディスクの領域を書き換えることになる。同様に、パーミッション、ファイルオーナーも共有される。file-a のパーミッションを変更すると file-b にも反映される。

ハードリンクの削除とリンク数
次に削除時のことを考えてみよう。file-a と file-b が同じファイルを指しているとして、file-a を削除したときに単純に i-node 414820 に対応する領域を消してしまうのはまずい。なぜならば、file-b を参照したときに i-node 414820 に対応する領域が残っていないと困るからである。それを避けるため、UNIX のファイルシステムはリンク数という情報を保持している。先程の ls -li の表示で、パーミッションの後の数字がリンク数である。

file-a しか存在しないときはリンク数は 1 であるが、file-b を作成するとリンク数が 2 に増えていることに注意してほしい。file-a を削除するとき、OS はリンク数を 1 減らす。
リンク数が 0 になったときにはじめてファイルの実体を削除する。
% ls -li file-a file-b (それぞれのリンク数は2)
414820 -rw-r--r-- 2 user group 10 Aug 4 14:49 file-a
414820 -rw-r--r-- 2 user group 10 Aug 4 14:49 file-b
% rm file-a (file-aを削除)
% ls -li file-b (リンク数が1になった)
414820 -rw-r--r-- 1 user group 10 Aug 4 14:49 file-b
上の例では、rm file-a でリンク数を1減らしてもリンク数が 0 にはならないので、i-node 414820 に対応するディスク領域は削除されないわけである。この状態で rm file-b を実行すると、リンク数は 0 になり、i-node 414820 に対応するディスク領域は消去される。

なお、一般的にディレクトリのハードリンクは作成できない。これは、循環ディレクトリができないようにするためである。例えば /hoge がディレクトリの場合、
% ln /hoge /hoge/dir
を実行すると、/hoge/dir/dir/dir/dir/dir/dir/.... という無限のディレクトリができることになる (/hoge/dir は /hoge と同じだから)。そのため、ディレクトリのハードリンクは作成できないことになっている。ただし、Solaris などでは root のみがディレクトリのハードリンクを作成できる(ln コマンドでは不可能。システムコール link(2) を使う必要がある)。しかし、一般的にはシンボリックリンクを使う方がよいだろう。

ハードリンクの制限
ファイルシステム (df コマンドで表示される 1行が 1ファイルシステム) をまたいだハードリンクを作成するこてゃできないことに注意。

これは、ハードリンクは異なるファイルが同じ i-node を指すことで実現されているが、ファイルシステムが異なると、全く違う i-node が付けられるからである。つまり/dev/sd0 の i-node 100 が /usr/hoge だったとしても、/dev/wd0 の i-node 100 は/var/hoge かもしれない。よって、/dev/wd0 の中のファイルと /dev/sd0 の中のファイルとでは、同じ i-node を共有することができないのである。

シンボリックリンクとは
次に、シンボリックリンクについて説明する。ln にオプションを付けるとシンボリックリンクが作成される。
% ln -s file-a file-b
とすることで、file-a の別名である file-b ができる。シンボリックリンクはハードリンクとは違い、参照先(実体)と参照元という区別がはっきりと存在する。これは ls -l で見るとわかりやすいだろう。
% ls -l file-a file-b
-rw-r--r-- 1 user group 0 Aug 1 16:14 file-a
lrwxrwxrwx 1 user group 3 Aug 1 16:14 file-b -> file-a
先頭のファイルタイプが「l」であることから、file-b は通常ファイルではなくシンボリックリンクであり、file-a を指していることがわかる。

シンボリックリンクは、参照先が存在しなくてもエラーとならない。つまり、file-a が存在しなくても
% ln -s file-a file-b
とすることができる。また、シンボリックリンクはハードリンクとは違って、別のファイルシステムへもリンクを張ることができる。

なお、
% cd /tmp; ln -s /home/foo/bar/sample

% ln -s /home/foo/bar/sample /tmp/sample
と同じである。つまり、他のディレクトリ中のファイルへのシンボリックリンクをカレントディレクトリに作成したかったら、
% ln -s /home/foo/bar/sample
と、シンボリックリンク名を省略できる。シンボリックリンクの削除をしたいときは、普通に rm コマンドを使えばよい。rm はシンボリックリンクの指す先ではなく、リンク自体を削除する。

シンボリックリンクのパーミッション
シンボリックリンク自体のパーミッションは全く意味を持たない。
lrwxrwxrwx 1 user group 3 Aug 1 16:14 file-b -> file-a
でも
l--------- 1 user group 3 Aug 1 16:14 file-b -> file-a
でも全く違いはない。有効なのはリンク先の file-a のパーミッションである。

ln コマンドのオプション
-f すでにリンクが張られていたら、リンクを付け替える。
% ln -s file link
% ln -s file2 link
ln: link: File exists
このようにリンクの「張り替え」のような作業をするとエラーとなるが -f オプションを付けると、この「張り替え」ができるようになる。
-s シンボリックリンクを張る。-s を付けないとハードリンクとなる。
>> FreeBSDオンラインマニュアル(man) FreeBSD ln(1)
>> Solaris10オンラインマニュアル(man) Solaris10 ln(1)
>> Linuxオンラインマニュアル(man) Linux ln(1)

読み方 ln (UNIXコマンド) [える・えぬ] このエントリーをはてなブックマークに追加

"LiNk" の略。