lnコマンドおさらい
宣言通り、LinuCの勉強中です。シンボリックリンクとハードリンクの挙動、毎回忘れてググってしまうので書き留めておく。 特に削除する時の挙動が曖昧になるので動作検証してちゃんと覚えたい。
シンボリックリンクとハードリンク
シンボリックリンクとハードリンクの違いの前に、Linuxにおけるファイルとは何かをおさらい。Linuxでは、ファイルをディスクに保存すると、ユニークなiノード番号が割り振られる。(ちなみにディレクトリも特殊な形のファイルである。)このiノードには、ファイルに関する様々な情報が保持されている。
例えば、ファイルのアクセス権やファイルサイズ、ファイル種別などのls -l
で閲覧できる情報などと、ディスク上の物理的な保存場所を示す情報などである。
物理的な保存場所に格納されているデータがファイルの実体であり、たとえ実体がひとつであってもその実体を参照するファイルが複数存在する、ということはありえる。これがハードリンク。
ハードリンクの場合は、元のファイルとハードリンクとして作成したファイルのどちらも同じiノードを持っていてファイルの実体がひとつ(つまり物理的な保存場所が同一)なので、この二つに区別はない。いずれかを編集すると当然両方に影響がある。 同一の実体ファイルに対して変更を加えているからである。ハードリンクが3つ、4つ、と増えても同じである。iノードはファイルシステムごとに管理されるため、ハードリンクはリンク元のファイルが存在する同一のファイルシステム上にしか作成できない。下記の例だと、file.originalが存在するファイルシステム上だけでこれをリンク元にしたハードコピーが作成できる。
シンボリックリンクは参照先のファイルの場所(実体ファイルの場所ではない)を示すファイル。いわゆるMacのエイリアス、Winでいうショートカット。シンボリックリンクを削除してもファイルの実体には影響がないし、逆にシンボリックリンクが残ったまま実体ファイルを削除することも可能。(ただしリンクはエラーとなる。)シンボリックリンクが保持している情報は、参照先のファイルのパスになるので別のファイルシステム上からリンクを作成することができる。
ハードリンクについて
ハードリンク作成時のコマンドはln リンク元(=実体) リンクファイル
。
ハードリンクの挙動
ハードリンクはiノードが全て同じ。また、左から3番目の数字は参照の数を表すので、ハードリンクが増えるたびに数値が増えていることがわかる。
1~ ❯❯❯ touch file.original
2~ ❯❯❯ ln file.original file.hard1
3~ ❯❯❯ ls -il file*
470677112 -rw-r--r-- 2 mochiko 2033490572 0 9 19 00:11 file.hard1
570677112 -rw-r--r-- 2 mochiko 2033490572 0 9 19 00:11 file.original
6~ ❯❯❯ ln file.hard1 file.hard2
7~ ❯❯❯ ls -il file*
870677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.hard1
970677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.hard2
1070677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.original
11~ ❯❯❯
コピーするとiノードは異なるものになるので編集してもお互い影響を受けない。
1~ ❯❯❯ cp -pi file.hard1 file.hard-copy
2~ ❯❯❯ ls -il file*
370677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
470677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.hard1
570677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.hard2
670677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.original
7~ ❯❯❯
8~ ❯❯❯ echo "Hello Linux" > file.original
9~ ❯❯❯ cat file.original
10Hello Linux
11~ ❯❯❯ cat file.hard1
12Hello Linux
13~ ❯❯❯ cat file.hard2
14Hello Linux
15~ ❯❯❯ cat file.hard-copy
16~ ❯❯❯
ハードリンクの削除
rm ハードリンク
or unlink ハードリンク
でハードリンクの削除が可能。
1~ ❯❯❯ ls -li file.original file.hard*
270677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
370677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.hard1
470677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.hard2
570677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.hard3
670677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.original
7~ ❯❯❯
8~ ❯❯❯ rm file.hard1
9~ ❯❯❯ ls -li file.original file.hard*
1070677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
1170677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.hard2
1270677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.hard3
1370677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:49 file.original
14~ ❯❯❯
15~ ❯❯❯ unlink file.hard3
16~ ❯❯❯ ls -li file.original file.hard*
1770677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
1870677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.hard2
1970677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.original
20~ ❯❯❯
ハードリンクが削除されてもそのファイルへの参照が残っていればファイルの実体が消えることはない。なので、もともとハードリンクの参照元となっていたfile.original
を先に削除しても他のハードリンクには影響がない。
1~ ❯❯❯ ls -li file.*
270677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.hard
370677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.original
4~ ❯❯❯ unlink file.original
5~ ❯❯❯ ls -li file.*
670677112 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:49 file.hard
7~ ❯❯❯
シンボリックリンクについて
シンボリックリンク作成時のコマンドはln -s リンク元(=実体) リンクファイル
。
シンボリックリンクの挙動
ls -l
で確認するとファイル種別はシンボリックリンクを表すl
となり、リンク元のファイル名も取得できている。ハードリンクに対してシンボリックリンクを作成することも可能。
1~ ❯❯❯ ln -s file.original file.symlink
2~ ❯❯❯ ls -il file.original file.sym*
370677112 -rw-r--r-- 3 mochiko 2033490572 0 9 19 00:11 file.original
470679436 lrwxr-xr-x 1 mochiko 2033490572 13 9 19 00:31 file.symlink@ -> file.original
5~ ❯❯❯
6~ ❯❯❯ ln -s file.hard2 file.symlink2
7~ ❯❯❯ ls -il file*
870677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
970677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:35 file.hard1
1070677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:35 file.hard2
1170677112 -rw-r--r-- 3 mochiko 2033490572 12 9 19 00:35 file.original
1270679436 lrwxr-xr-x 1 mochiko 2033490572 13 9 19 00:31 file.symlink@ -> file.original
1370679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
14~ ❯❯❯
シンボリックリンクのコピーには、オプションの-d
が必要。オプションを付けないでコピーすると、リンク元のファイルの中身をファイルとしてコピーしてしまう。file.symlink-copy
のファイル種別がリンクではなく通常ファイルになっているのがわかる。
1~ ❯❯❯ cp file.symlink file.symlink-copy
2~ ❯❯❯ ls -il file.sym*
370679436 lrwxr-xr-x 1 mochiko 2033490572 13 9 19 00:31 file.symlink@ -> file.original
470679879 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:42 file.symlink-copy
570679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
6~ ❯❯❯
次の例のふたつは一見同じに見えるが、上段はシンボリックリンクのリンク元であるfile.original
をcatしたもので、下段は先ほどの-dなしのシンボリックリンクのコピーによってfile.original
の内容がfile.symlink-copy
のファイルに書き込まれたものをcatしている。リンク元のデータが書き換わっても完全に別のファイルとして存在しているfile.symlink-copy
は影響を受けない。
1~ ❯❯❯ cat file.symlink
2Hello Linux
3~ ❯❯❯ cat file.symlink-copy
4Hello Linux
5~ ❯❯❯
6~ ❯❯❯ echo "Hello World" > file.original
7~ ❯❯❯ cat file.symlink
8Hello World
9~ ❯❯❯ cat file.symlink-copy
10Hello Linux
11~ ❯❯❯
シンボリックリンクの削除
rm シンボリックリンク
or unlink シンボリックリンク
で削除が可能。シンボリックリンクを単純に削除したい場合はunlinkコマンドを利用する方が安全。
rmコマンドを使う際はrm file.symlink/
とスラッシュを付けて実行するとリンクの参照先のファイル自体が削除されてしまうので注意が必要である。
1~ ❯❯❯ rm file.symlink
2~ ❯❯❯ ls -li file.original file.sym*
370677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.original
470679879 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:42 file.symlink-copy
570679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
670681303 lrwxr-xr-x 1 mochiko 2033490572 13 9 19 01:00 file.symlink3@ -> file.original
7~ ❯❯❯
8~ ❯❯❯ unlink file.symlink3
9~ ❯❯❯ ls -li file.original file.sym*
1070677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.original
1170679879 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:42 file.symlink-copy
1270679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
13~ ❯❯❯
スラッシュをつけて実行するとリンク元のファイルfile.hard2
自体が削除されている。その結果、file.symlink2
は参照する先がなくてエラーを生じる。
1~ ❯❯❯ ls -li file.*
270677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
370677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.hard2
470677112 -rw-r--r-- 2 mochiko 2033490572 12 9 19 00:49 file.original
570679879 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:42 file.symlink-copy
670679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
7~ ❯❯❯
8~ ❯❯❯ rm file.symlink2/
9~ ❯❯❯ ls -li file.*
1070677358 -rw-r--r-- 1 mochiko 2033490572 0 9 19 00:11 file.hard-copy
1170677112 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:49 file.original
1270679879 -rw-r--r-- 1 mochiko 2033490572 12 9 19 00:42 file.symlink-copy
1370679720 lrwxr-xr-x 1 mochiko 2033490572 10 9 19 00:39 file.symlink2@ -> file.hard2
14~ ❯❯❯ cat file.symlink2
15cat: file.symlink2: No such file or directory
16~ ❯❯❯
蛇足。上記のようなまとめを書いていて、途中で「リンク元」と「リンク先」がどっちがどっちか分からなくなった。個人的にオリジナルの方を「リンク元」と呼ぶのに違和感を感じてしまう。参照される先のファイル、というのと混ざるためかもしれない。他の人のブログなどで誤用されていたこともあり、ますますあやふやになって調べたら、同じようなことを書いている人がいて、私だけではなかったのだなと妙な安心を抱いた。
とにかく「リンク元」が「オリジナル」だって思うことにします。
私もこれで行こうと思います。