ハードリンクとシンボリックリンクの違いについて挙動を調べてみた

ハードリンクとシンボリックリンクの違いを知りたくて調べてみました。

環境はこちらです。

```
# cat /etc/redhat-release
CentOS Linux release 7.7.1908 (Core)
```

### ハードリンクとは？
ハードリンクとは、ファイルシステムの機能の一つで、~~あるファイルやディレクトリの実体に複数の名前を付け、それぞれが実際のファイル名/ディレクトリ名として等しく機能するようにしたもの。ハードリンクを作成すると同じファイルを持つこととなる。~~
ファイルの実体に名前を付けた時の ( どこかのディレクトリにファイル名を登録する )、ファイルの実体とファイル名の対応自体がハードリンクで、複数つけることもできる。

シンボリックリンクとの違いは、シンボリックリンクは指定したファイルに繋がるパスを持ったファイルが作成されるが、ハードリンクは指定したファイルそのものと同じデータを持つ事になる。
### シンボリックリンクとは？
指定したファイルのパスを持つファイルが作成される。そのため、ファイルとしては新たに作成される。

# ハードリンクを作成してみた

ファイルをファイル名付きで作成した時点でハードリンクは作成される。なので、`vi 新しいファイル名`や`echo "hoge" > 新しいファイル名`などをしてファイルを作成した時点でハードリンクが一つ自動で作成される。
ここでは、作成したファイル（ハードリンク一つのファイル実体)に対して追加でハードリンクを作成してみる。
lnコマンドを使ってハードリンクを作成することができる。
ln 元のファイル　ハードリンクの名前
ハードリンクを作成した場合、元のファイルとハードリンクのinode番号（一番左の番号）が同じであることがわかる。
ここでは、8409199のこと。
inode番号はファイルの実態であるため、見かけはファイルが二つあるように見えるが、実態としては一つのファイルであると言える。

```
# echo "hogehoge2" > test
# ln test hardlink
# ls -li
8409199 -rw-r--r--  2 root root   10  6月 24 21:13 hardlink
8409199 -rw-r--r--  2 root root   10  6月 24 21:13 test
```

# シンボリックリンクを作成してみた
続いてシンボリックリンクを作成してみる。
ln -sでシンボリックリンクを作成できる。
下の結果から、inode番号が異なるファイルが作成されたことがわかる。これは、指定したファイルを参照するためのファイルが作成されたとみることができる。

```
# ls -il test symblink hardlink 
8409199 -rw-r--r-- 2 root root 10  6月 24 21:13 hardlink
8409209 lrwxrwxrwx 1 root root  5  6月 24 21:53 symblink -> test
8409199 -rw-r--r-- 2 root root 10  6月 24 21:13 test
```

ちなみに各ファイルの中身をみてみると全て同じであることがわかる。
全て同じファイルを参照しているため！

```
# cat test
hogehoge2
# cat hardlink 
hogehoge2
# cat symblink
hogehoge2
```

シンボリックリンクのファイル内を変更しても、全てのファイルが変更される。
全て同じファイルを参照しているため！！

```
# echo "add hoge" >> symblink
# cat test
hogehoge2
add hoge
# cat hardlink 
hogehoge2
add hoge
# cat symblink
hogehoge2
add hoge
```

# 異なるファイルシステムにハードリンク・シンボリックリンクを作成してみた！
ハードリンクはファイルシステム内で一意のinode番号が割り振られており、異なるファイルシステムにハードリンクを作成することはできない。その挙動をみてみる。

まずファイルを作成してみる。

```
# touch fileA
# ls -i fileA 
8409208 fileA
```
dfコマンドでファイルシステムを確認。ホームディレクトリで作業していたため、fileAのあるファイルシステムはマウント位置が/のところとなっている。今回は/dev/shm以下にハードリンクを作成した時の挙動をみてみる。

```
# df
ファイルシス            1K-ブロック    使用  使用可 使用% マウント位置
devtmpfs                     495352       0  495352    0% /dev
tmpfs                        507412       0  507412    0% /dev/shm
tmpfs                        507412    6876  500536    2% /run
tmpfs                        507412       0  507412    0% /sys/fs/cgroup
/dev/mapper/centos-root     6486016 1198776 5287240   19% /
/dev/sda1                   1038336  139372  898964   14% /boot
tmpfs                        101484       0  101484    0% /run/user/0
```
ハードリンクを作成するとエラーが発生する。これにより異なるファイルシステムにハードリンクを作成することができないことがわかった。
シンボリックリンクの場合は異なるファイルシステムでもリンクを作成することができる。
しかし、リンク切れが発生してしまう。

```
# ln fileA /dev/shm/fileA-2
ln: `/dev/shm/fileA-2' から `fileA' へのハードリンクの作成に失敗しました: 無効なクロスデバイスリンクです
# ln -s fileA /dev/shm/fileA-2
# cat /dev/shm/fileA-2
cat: /dev/shm/fileA-2: シンボリックリンクの階層が多すぎます
# file /dev/shm/fileA-2
/dev/shm/fileA-2: broken symbolic link to `fileA'
```

# 続いて作成したハードリンクを異なるファイルシステムに移動させてみる
fileAのハードリンクを三つ作成し、そのうちの一つを異なるファイルシステムに移動させてみる。

```
# ln fileA fileA-2
# ln fileA-2 fileA-3
# ls -li fileA*
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA-2
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA-3
```
このうち、file-3を/dev/shm配下に移動してみる。
ls -lの結果から移動後にハードリンク数が減っていることがわかる。
移動まえ）
8409208 -rw-r--r-- 3 root root 0  6月 24 21:35 fileA-2
　　　　　　　　　↑ここが3となっており、ハードリンクが三つあると表記されている。
移動後）
8409208 -rw-r--r-- 2 root root 0  6月 24 21:35 fileA-2
file-1とfile-2はハード数が2になっている。
18911 -rw-r--r-- 1 root root 0  6月 24 21:35 /dev/shm/fileA-3
file-3に関しては1つになっている。

```
# mv fileA-3 /dev/shm/
# ls -li fileA*
8409208 -rw-r--r-- 2 root root 0  6月 24 21:35 fileA
8409208 -rw-r--r-- 2 root root 0  6月 24 21:35 fileA-2
# ls -li /dev/shm/fileA-3 
18911 -rw-r--r-- 1 root root 0  6月 24 21:35 /dev/shm/fileA-3
```
ファイルの中身を編集してみると、異なるファイルシステムに移動したファイル（fileA-3）には変更が反映されていない。

```
# echo "hello" > fileA
# cat fileA
hello
# cat fileA-2 
hello
# cat /dev/shm/fileA-3 
（（何も表示されない！！））
```
このことから、mvコマンドによりハードリンクを移動させると、元のファイルシステムからは削除され、指定したファイルシステム内にファイルが新しく作成される挙動になっていることがわかった。

# 終わりに
今回は、ハードリンクとシンボリックリンクについて調べて、挙動を確認してみました。
基本的なことはまだまだわからないことも多いですが、一つずつ勉強していこうと思います。

参考）
https://qiita.com/lnznt/items/6178e1c5f066f22fe9c2#%E7%95%B0%E3%81%AA%E3%82%8B%E3%83%95%E3%82%A1%E3%82%A4%E3%83%AB%E3%82%B7%E3%82%B9%E3%83%86%E3%83%A0%E3%81%B8%E3%81%AE-mv