【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で言う「ショートカット」がシンボリックリンクに値します。

シンボリックリンクはファイルだけでなくディレクトリに対しても作成することができます。

シンボリックリンクとは?

作成する状況やメリット

ではどのような時にシンボリックリンクを使うのか考えてみます。

大きなメリットとしてはカレントディレクトリを変更しなくてもまるで配下にあるように対象ファイル(ディレクトリ)にアクセスできることでした。

例えば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)とは?

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ノードのリンクは切れていないため参照できてしまうのです。

ディスク上のデータはずっと残る訳ではなく元ファイルとのリンクが切れていた場合他のデータを保存時に上書きできる領域として当てられます。ディスク容量が他で使われるまでは残っている可能性があるということだと思います。

まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。

ご覧いただきありがとうございました。

searchbox

スポンサー

ProFile

ame

趣味:読書,プログラミング学習,サイト制作,ブログ

IT嫌いを克服するためにITパスを取得しようと勉強してからサイト制作が趣味に変わりました笑
今はCMSを使わずこのサイトを完全自作でサイト運営中〜

New Article

index