LoginSignup
16
7

More than 5 years have passed since last update.

lnコマンドで作成するリンクの勉強をしようとしたら、思っていたより複雑だった

Posted at

lnコマンドで生成するリンクのことを良く分かっていなかったので勉強しました。長いので最後にまとめがあります。

使ってみましょう

ファイルの作成

準備としてダミーファイルを作成します。ファイルの内容は'Hello, Qiita!'にしましょう。

[centos@ip-10-0-1-10 ~]$ echo 'Hello, Qiita!' > target
[centos@ip-10-0-1-10 ~]$ ls -i
12843345 target

ls -iは、ファイルのiノード番号を表示するコマンドです。iノード番号とは、ファイルとディスク上に存在するファイルの実体データを対応させる番号のことです。ファイルとiノード番号とデータは次のような関係になっています。

ファイル名 iノード番号 データ
target 12843345 Hello, Qiita!

ln (ハードリンク)

オプション無しのln target link1でリンクを作成します。

[centos@ip-10-0-1-10 ~]$ ln target link1
[centos@ip-10-0-1-10 ~]$ ls -i
12843345 link1  12843345 target
ファイル名 iノード番号 データ
link1 12843345 Hello, Qiita!
target 12843345 Hello, Qiita!

このように作成するリンクをハードリンクと呼びます。targetとlink1は同じiノード番号を持つため、ディスク上で全く同じデータを参照しています。確かめるためにちょっと実験をしてみましょう。

[centos@ip-10-0-1-10 ~]$ echo 'Hi, Qiita!' > target
[centos@ip-10-0-1-10 ~]$ cat link1
Hi, Qiita!

targetファイルの内容を上書きしたところ、link1の内容も変化しました。

ハードリンクには「リンク」と名が付いていますが、作成した後はどちらが元のファイルでどちらがリンクであるかという区別はつきません(実体は全く同じですから!)。どのような場面で利用するのかは良く分かりません。

cp (コピー)

ハードリンクに似たようなコマンドで、非常に良く使われるcpコマンドがあります。iノード番号に注意してみると、lnとの違いが分かりやすくなります。

[centos@ip-10-0-1-10 ~]$ cp target copy1
[centos@ip-10-0-1-10 ~]$ ls -i
12843349 copy1  12843345 link1  12843345 target
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Hi, Qiita!
target 12843345 Hi, Qiita!

iノード番号が違うので、copy1はtargetとは全く別のものです。どちらかの内容を変更しても、もう一方には影響がありません。一般的なファイルのコピーはこちらですね。

ln -s (シンボリックリンク)

lnコマンドに-sオプションをつけることで、シンボリックリンクと呼ばれるリンクを作成することができます。一般的にリンクと言う場合にはこのシンボリックリンクを指す事が多いです。

[centos@ip-10-0-1-10 ~]$ ln -s target link2
[centos@ip-10-0-1-10 ~]$ ls -li
total 12
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy1
12843345 -rw-rw-r--. 2 centos centos 11 Aug 31 13:01 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843345 -rw-rw-r--. 2 centos centos 11 Aug 31 13:01 target
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Hi, Qiita!
link2 12843350 (targetを参照)
target 12843345 Hi, Qiita!

link2の内容はtargetと同一となります。targetの内容を変えるとlink2も変わります。逆にlink2の内容を変えるとtargetも変わります。

[centos@ip-10-0-1-10 ~]$ cat link2
Hi, Qiita!
[centos@ip-10-0-1-10 ~]$ echo 'Penguins like fish.' > target
[centos@ip-10-0-1-10 ~]$ cat link2
Penguins like fish.
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Penguins like fish.
link2 12843350 (targetを参照)
target 12843345 Penguins like fish.
[centos@ip-10-0-1-10 ~]$ echo 'Penguins swim fast.' > link2
[centos@ip-10-0-1-10 ~]$ cat target
Penguins swim fast.
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843345 Penguins swim fast.

シンボリックリンク先を削除することもできます。この場合、あて先不在のリンクだけが残ります。

[centos@ip-10-0-1-10 ~]$ rm target
[centos@ip-10-0-1-10 ~]$ cat link2
cat: link2: No such file or directory
[centos@ip-10-0-1-10 ~]$ ls -li
total 8
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy1
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Penguins swim fast.
link2 12843350 (target[存在しない]を参照)

ターゲットを再度作成することで、シンボリックリンクはそのまま使用できます。

[centos@ip-10-0-1-10 ~]$ echo 'Penguins are back now.' > target
[centos@ip-10-0-1-10 ~]$ ls -li
total 12
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy1
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
[centos@ip-10-0-1-10 ~]$ cat link2
Penguins are back now.
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843351 Penguins are back now.

シンボリックリンクのコピー

cpコマンドでリンクをコピーすることも出来ます。この場合、オプション無しではリンク参照先ファイルのコピーがファイルとして作成され、オプション-dを付けると同じターゲットを参照するシンボリックリンクが作成されます。

[centos@ip-10-0-1-10 ~]$ cp link2 copy2
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy1
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843351 Penguins are back now.
[centos@ip-10-0-1-10 ~]$ cp -d link2 copy3
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy1
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843353 lrwxrwxrwx. 1 centos centos  6 Aug 31 14:52 copy3 -> target
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy1 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
copy3 12843353 (targetを参照)
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843351 Penguins are back now.

mv (ファイル名の変更)

mvはファイル名を変更するコマンドです。ファイルの持つiノード番号は変わりません。

[centos@ip-10-0-1-10 ~]$ mv copy1 copy11
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy11
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843353 lrwxrwxrwx. 1 centos centos  6 Aug 31 14:52 copy3 -> target
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy11 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
copy3 12843353 (targetを参照)
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843351 Penguins are back now.

シンボリックリンクで指定されているファイルをmvした場合、シンボリックリンクはリンク切れとなります。シンボリックリンクが見ているのはリンク先のファイル名であって、iノード番号ではありません。

[centos@ip-10-0-1-10 ~]$ mv target target2
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy11
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843353 lrwxrwxrwx. 1 centos centos  6 Aug 31 14:52 copy3 -> target
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target2
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy11 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
copy3 12843353 (target[存在しない]を参照)
link1 12843345 Penguins swim fast.
link2 12843350 (target[存在しない]を参照)
target2 12843351 Penguins are back now.

戻しておきます。

[centos@ip-10-0-1-10 ~]$ mv target2 target
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy11
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843353 lrwxrwxrwx. 1 centos centos  6 Aug 31 14:52 copy3 -> target
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link2 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy11 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
copy3 12843353 (targetを参照)
link1 12843345 Penguins swim fast.
link2 12843350 (targetを参照)
target 12843351 Penguins are back now.

シンボリックリンクをmvした場合は、シンボリックリンク自身のファイル名が変わります。リンク先のファイルには影響がありません。

[centos@ip-10-0-1-10 ~]$ mv link2 link3
[centos@ip-10-0-1-10 ~]$ ls -li
total 16
12843349 -rw-rw-r--. 1 centos centos 11 Aug 31 13:40 copy11
12843352 -rw-rw-r--. 1 centos centos 23 Aug 31 14:48 copy2
12843353 lrwxrwxrwx. 1 centos centos  6 Aug 31 14:52 copy3 -> target
12843345 -rw-rw-r--. 1 centos centos 20 Aug 31 14:38 link1
12843350 lrwxrwxrwx. 1 centos centos  6 Aug 31 13:40 link3 -> target
12843351 -rw-rw-r--. 1 centos centos 23 Aug 31 14:42 target
[centos@ip-10-0-1-10 ~]$
ファイル名 iノード番号 データ
copy11 12843349 Hi, Qiita!
copy2 12843352 Penguins are back now.
copy3 12843353 (targetを参照)
link1 12843345 Penguins swim fast.
link3 12843350 (targetを参照)
target 12843351 Penguins are back now.

まとめ

とても長くなってしまったので、まとめます。

  • ln: 同じiノード番号でファイルをコピーする。
  • mv: 同じiノード番号でファイル名を変更する。
  • ln -s: シンボリックリンクを作成する。
  • cp: 異なるiノード番号でファイルをコピーする。シンボリックリンクを対象にした場合には、シンボリックリンクの参照先がコピーされる。
  • cp -d: 異なるiノード番号でファイルをコピーする。シンボリックリンクを対象にした場合には、シンボリックリンク自身がコピーされる。

シンボリックリンクって何: 参照先ファイル名情報を持つ特殊なファイル。読み書きなどの操作は参照先ファイルに適用されるが、mvやrmやcp -dシンボリックリンク自身に適用される。
iノード番号って何:ファイル名とディスク上のデータを対応させる番号

16
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
16
7