【Linux】シンボリックリンクとハードリンクの違いとは?作成方法とiノード(index)
この記事からわかること
- Linux:シンボリックリンクとは?
- シンボリックリンクとハードリンクの違い
- 作成方法やルールコマンド
- iノード(Index Node)とは?
index
[open]
\ アプリをリリースしました /
友達や家族の誕生日をメモ!通知も届く-みんなの誕生日-
posted withアプリーチ
Linuxの仕組みの1つであるシンボリックリンクとは一体どのようなものなのか、またハードリンクとの違いや作成方法をまとめていきます。
シンボリックリンクとは?
シンボリックリンクとは指定のファイルに対して作成できる別名でアクセスできるようにするリンクのことです。
シンボリックリンクはフォルダ(ディレクトリ)の中に設置して使います。例えば「dev」ディレクトリの中に「sample.txt」がありカレントディレクトリが「public」だとします。
├── Home
│ ├── dev
│ └── sample.txt
│
│ └── public カレントディレクトリ(.)
│ ├── sample.txtのシンボリックリンク(link-sample.txt)
│ ├── index.html
│ └── css
│ └── style.css
カレントディレクトリから「sample.txt」にアクセスするには階層をあがって参照(../dev/sample.txt
)するしかありません。しかしpublic内に「sample.txt」のシンボリックリンクを貼るとpublic/シンボリック名
で「sample.txt」にアクセスできるようになります。
このようにシンボリックリンクは全く別階層のファイルに、さも同階層(の中)にあるかのようにアクセスできる仕組みのことになります。Macで言う「エイリアス」、Windowsで言う「ショートカット」がシンボリックリンクに値します。
シンボリックリンクはファイルだけでなくディレクトリに対しても作成することができます。
シンボリックリンクとは?
- ファイルに別名をつける仕組み
- 作成すると別階層からのアクセスが簡単になる
- 作成することを貼ると言ったりする
- ファイルやディレクトリに対して使用可能
- 作成方法はコマンドラインからコマンドを入力
- Mac→エイリアス/Windows→ショートカット
作成する状況やメリット
ではどのような時にシンボリックリンクを使うのか考えてみます。
大きなメリットとしてはカレントディレクトリを変更しなくてもまるで配下にあるように対象ファイル(ディレクトリ)にアクセスできることでした。
例えばWebページを表示させるときは公開範囲にあるディレクトリに公開範囲外の階層のディレクトリのシンボリックリンクを貼ることでURLでのアクセスを可能にすることができたりします。
├── Home
│ ├── NoPublic
│ └── web-linux-symboliclink.php
│
│ └── public
│ // web-linux-symboliclink.phpへのリンク
│ ├── web-linux-symboliclink
│ ├── index.html
│ └── css
│ └── style.css
シンボリックリンクを実際に使用している記事
シンボリックリンクの貼り方とコマンド
シンボリックリンクを作成するにはコマンドラインからlnコマンド(命令)を実行します。オプションにはシンボリックリンクを表す-s
を、引数には対象ファイルと作成されるシンボリック名を指定するとカレントディレクトリ内に指定したシンボリック名のシンボリックリンクファイルが作成されます。
シンボリックリンク作成コマンド
$ ln -s 対象ファイル シンボリック名
例えば先ほどの「sample.txt」の場合は以下のようなコマンドになります。 リンクファイル名に制限はない(正確には特殊文字は一部使用できません)ので分かりやすい名前をつけてあげることをおすすめします。
$ ln -s ../dev/sample.txt link-sample.txt
シンボリックリンクを貼ることでカレントディレクトリ(今回はpublic)からシンボリック名だけの記述でアクセス可能になります。試しにファイルを開くcat
コマンドを実行すると問題なく「dev」>「sample.txt」と同じ内容が表示されます。
$ cat link-sample.txt
これはサンプルのテキストです。
シンボリックリンクを確認する
作成してあるシンボリックリンクを確認するにはls
コマンドのオプションにリンクファイルを表示させる-l
を指定します。その中で->
がついている項目がリンクファイルを表しています。
$ ls -l
lrwxr-xr-x 1 user staff 26 4 13 19:30 link-sample.txt -> ../dev/sample.txt
-rw-------@ 1 user staff 8917 4 13 19:01 index.html
drwxr-xr-x 4 user staff 128 3 4 21:15 css>
ここではシンボリック名 -> リンク先パス
の形式で表示されます。
lrwxr-xr-x 〜 シンボリック名 -> リンク先パス
また一番左端がファイル種別を表しているのでそこからもリンクファイルということが識別できます。後続のrwxr-xr-x
部分はパーミション(権限)設定になります。
ファイル種別 | 概要 |
---|---|
- | 通常ファイル |
l | リンクファイル |
d | ディレクトリ |
c/d | 特殊ファイル |
シンボリックリンクを削除する
削除するにはunlink
コマンドで引数にはシンボリック名を指定します。
$ unlink シンボリック名
CUI(コマンドライン)での削除はコマンド実行ですが、GUI(マウス操作)の場合はでも通常のファイルのように削除することができます。エイリアスやショートカットを作成から削除までマウス操作で行えるようにCUIでも同様の操作ができるだけにすぎません。
ハードリンクとは?
ln
コマンドは実はシンボリックリンクを貼るコマンドではなくリンクを貼るコマンドです。リンクには実は「シンボリックリンク」と「ハードリンク」の2種類があります。
オプションに-s
を指定することでシンボリックリンクを貼るコマンドになり、オプションを省略するとハードリンクを作成するコマンドになります。
ハードリンクを作成するコマンド
$ ln 対象ファイル ハードリンク名
ハードリンクの基本的な仕組みや役割はシンボリックリンクと変わりません。なので最初の状況と同じようにハードリンクとしてリンクを貼ることも可能です。
├── Home
│ ├── dev
│ └── sample.txt
│
│ └── public カレントディレクトリ(.)
│ ├── sample.txtのハードリンク(hard-link-sample.txt)
│ ├── index.html
│ └── css
│ └── style.css
正常に動作する
$ ln ../dev/sample.txt hard-link-sample.txt
$ cat hard-link-sample.txt
これはサンプルのテキストです。
シンボリックリンクとハードリンクの違い
項目 | シンボリックリンク | ハードリンク |
---|---|---|
コマンド | ln -s | ln |
リンク名(GUIで操作する場合) | なんでもOK | 拡張子に注意 |
元ファイルの削除 | 参照不可になる | 参照可能のまま |
iノード(index Node)番号 | 元ファイルと別 | 元ファイルと同じ |
指定するリンク名の注意点(GUI)
これはGUI上で操作する場合の話です。
シンボリックリンクの場合は「sample.txt」のリンク名を「sample.jpg」のように別の拡張子で指定しても正常にリンクとして機能し、元ファイルを参照することができます。
一方ハードリンクの場合は「sample.txt」のリンク名を「sample.jpg」のように別の拡張子で指定するとそのリンク名からはアクセスしにくくなってしまいます。
これはGUIの場合アクセスするアプリケーションを拡張子で自動分岐しているため画像形式と認識し写真などのアプリで開こうとするためです。なのでマウスの右クリックで「このアプリケーションで開く」からテキストエディタなどを選択すると通常通りに開くことができます。
元ファイルの削除
元ファイル(この場合dev > sample.txt)を削除した場合の挙動にも違いがあります。
// ハードリンクを貼る
$ ln ../dev/sample.txt hard-link-sample.txt
// シンボリックリンクを貼る
$ ln -s ../dev/sample.txt link-sample.txt
// 元ファイルを削除
$ rm -i ../dev/sample.txt
remove sample.txt? y
// ハードリンクを表示
$ cat hard-link-sample.txt
これはサンプルのテキストです。
// シンボリックリンクを表示
$ cat link-sample.txt
cat: link-sample.txt: No such file or directory
元ファイルが削除された場合でもハードリンクの方は中身を表示できますが、シンボリックリンクの方は「そのようなファイルは存在しないよ」と出てしまいます。
これには次に解説する「iノード(index Node)」が関係してきます。
iノード(index Node)とは?
iノード(index Node)とはUnix系のOSやLinuxなどで使われているファイルシステム「ext2」 や「ext4」などのファイルやディレクトリを管理している仕組みのことです。
デスクトップ上にファイルが保存された時に実際のデータ領域とは別にiノード領域も確保されます。iノードにはファイル名以外のメタ情報(サイズ/作成日時/パーミションなど)やディスク上(HDDやSSD)の管理場所が保存され、ファイルに対して一意のiノード(inode)番号が振られ管理できるようにされています。
ファイルに通常にアクセスするときもiノード番号が使われています。ファイル名とiノード番号は対応表が内部的に作成されるので両者はその表を元に繋がっていてiノード番号を検索することで保存されている場所情報を取得し、実際のファイルを表示させることができるようになります。
iノード(index Node)とは?
- Unix系のOSやLinuxなどで使われている
- ファイルやディレクトリを管理する仕組み
- ext2が代表例
- iノード領域が存在
- 領域内にファイルのメタ情報や場所情報
- 場所情報はパスではなくディスク上
- 一意のiノード番号で管理
- ファイル名は管理されていない
- ファイル名とiノード番号は対応表有り
- 実はiノード番号を頼りにファイルを検索、表示させている
iノード(index Node)番号を確認する
iノード(index Node)番号はls
コマンドのオプション-i
を実行すると確認できます。するとiノード(index Node)番号 ファイル名
の形式で表示されます。
$ ls -i
11623060 hard-link-sample.txt 11699317 link-sample.txt
11689340 index.html 5550601 css
上記の通りiノード(index Node)番号はリンクファイルにも振られていることが分かります。ではリンク元も確認してみます。
$ cd ../dev
$ ls -i
11623060 sample-file.txt
実はよくみると元ファイルとハードリンクのiノード(index Node)番号は同じですがシンボリックリンクのiノード(index Node)番号は異なることに気づくと思います。
これが元ファイルを削除したときに起こる挙動の違いを生み出す原因です。
シンボリックリンクを作成するとリンク名に対応した新しいiノード(index Node)番号が振られ元ファイルへの参照パスが場所情報として格納されます。参照パスなので元ファイルが削除または別階層に移動しただけでもリンクは途切れてしまいます。
●ファイル名とiノード番号対応表
元ファイル名 11623060
ハードリンク名 11623060
シンボリックリンク名 11699317
●iノード領域
11623060 ディスク場所 メタ情報
11699317 参照パス
- ハードリンク→削除されてもディスク上の管理場所にアクセス可能
- シンボリックリンク→削除されると参照パスしかないためアクセス不可
ファイルを削除してもデータを参照できる理由
先に少し答えを書きましたがファイルを削除したのにハードリンクでは中身を参照できるのは不思議に思います。
実はこれはファイルを削除した時に完全に抹消されている訳ではなくディスクの中にはまだ残っているために参照できるのです。
ファイルデータは基本的にHDDやSSDなどのディスクに書き込まれて保存されています。デスクトップ(GUI)やコマンドライン(CUI)からファイルを参照するとパスではなく、ディスクの保存場所を読みにいくことで表示が可能になっています。
ではGUIやCUIでファイルを削除は一体何をしているのか。それは「iノードとファイル名の対応表からデータを削除」です。これによりファイル名とiノードのリンクが切れディスクの保存先の特定は不可能になります。しかしディスク上のデータは消されないかつハードリンク名とiノードのリンクは切れていないため参照できてしまうのです。
ディスク上のデータはずっと残る訳ではなく元ファイルとのリンクが切れていた場合他のデータを保存時に上書きできる領域として当てられます。ディスク容量が他で使われるまでは残っている可能性があるということだと思います。
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。