104.6 レッスン 1
Certificate: |
LPIC-1 |
---|---|
Version: |
5.0 |
Topic: |
104 デバイス、Linuxファイルシステム、ファイルシステム階層標準 |
Objective: |
104.6 ハードリンクとシンボリックリンクの作成と変更 |
Lesson: |
1 of 1 |
はじめに
Linuxにはリンクという特別な種類のファイルがあります。このレッスンでは、リンクとは何かを説明し、リンクを移動させるとどうなるかなどを学びます。
リンクを理解する
前のレッスンで説明したように、Linuxではすべてがファイルとして扱われます。ファイルの中には、リンク という特別な種類のファイルがあります。リンクには2種類あります。
- シンボリックリンク
-
ソフトリンク とも呼ばれます。別のファイルのパスを指し示します。指し示されるファイル(ターゲット)を削除すると、シンボリックリンクが存在していても、指し示されるものがなくなっているので、機能しなくなります。
- ハードリンク
-
元のファイルの2つ目の名前だと考えてください。コピー(複製)ではありません。ディスク上の同じ場所(inode)を指す別の項目(エントリ)です。
Tip
|
inode とは、ファイルやディレクトリなどの属性(メタデータ)を格納したデータ構造です。属性には、パーミッション、所有者・所有グループ、ファイル本体を収めたディスクブロックの位置などがあります。inodeを参照すると、ファイル名(パス名)以外のファイルに関する(データの位置を含む)すべての情報がわかりますから、ファイルそのものを表しているデータ構造であるといえます。すべてのファイルは1つのinodeに結びつけられていて、inodeのリスト(inodeテーブル)はディスク上の特別な位置に置かれています。いわば、inodeテーブルはファイルシステム内の全てのファイルに対する索引(index)であり、index nodeがinodeという名前の由来です。 |
ハードリンク
ハードリンクを作成する
ハードリンクを作成するコマンドは ln
です。次のように実行します。
$ ln TARGET LINK_NAME
TARGET
にはすでに存在しているファイル(リンクが指し示すことになるファイル)を指定します。LINK_NAME
には作成するリンクの名前を指定します。TARGET
も LINK_NAME
も、カレントディレクトリではない場合には、フルパスを指定します。例えば次のようなコマンドです。
$ ln target.txt /home/carol/Documents/hardlink
このコマンドは、カレントディレクトリにある target.txt
へのハードリンクを、/home/carol/Documents/
ディレクトリ内に hardlink
という名前で作成します。
第二引数(LINK_NAME
)を省略すると、パス名を除いたターゲットと同じ名前のリンクをカレントディレクトリに作成します。
ハードリンクを管理する
ハードリンクを作成することは、TARGETと同じinodeを指す、LINK_NAMEというディレクトリエントリを作成することです。ディレクトリの実体はそのディレクトリ内に存在するファイル名とinodeの対応表であり、そのようにしてinodeと対応づけられるファイル名のことをディレクトリエントリと呼びます。作成したハードリンク(LINK_NAME)と元のファイル名(TAREGT)は、異なるディレクトリ内に存在しているとしても、同じinodeを指し示すことになります。ハードリンクからでも元のファイル名からでも、同じinodeのファイルを指すのですから、そのファイルの内容が変更されます。ハードリンクを削除しても元のファイル名を削除しても、残っているほうの名前からそのファイルを参照できます。
ファイルを「削除」するときには、データが実際にディスクから消去されるわけではなく、ディスク上のデータに対応するinodeを指すディレクトリエントリが削除されます。同じinodeを指す別のディレクトリエントリ(ハードリンク)があれば、データにアクセスできるのです。いわば三叉路(Y字路)のようなものであり、同じ地点に向かう一つの路を塞いだとしても、もう一つの路からたどり着けるというわけです。
ls
に -i
オプションを指定して実行すると、このことを確かめられます。以下の例を見てみましょう。
$ ls -li total 224 3806696 -r--r--r-- 2 carol carol 111702 Jun 7 10:13 hardlink 3806696 -r--r--r-- 2 carol carol 111702 Jun 7 10:13 target.txt
パーミッションの前に表示されている数字がinodeです。hardlink
と target.txt
の両方とも同じ数字(3806696
)です。これは一方が他方のハードリンクだからです。
上記の例ではファイル名から区別できるように見えるかもしれませんが、実は、どちらが元ファイルでどちらがハードリンクかを区別できません。どちらも仕組みとしてはまったく同じものなのです。
ハードリンクを作成すると リンク数 が増えることにも注目してください。リンク数は、ls -l
を実行するとパーミッションの直後に表示される数値のことです。ファイルを作成したときの値は 1
(ディレクトリを作成したときの値は 2
)で、ハードリンクを作成するたびに1ずつ増えます。そういうわけで、上記の例ではリンク数が 2
になっています。
シンボリックリンクとは異なり、(ディレクトリのループが発生しうるため)ディレクトリを指し示すハードリンクを作成することはできません。また、(inodeはファイルシステムごとに決まるため)ターゲットと別のファイルシステム内にハードリンクを作成することもできません。
ハードリンクを移動(削除)する
ハードリンクは通常のファイルと同じように扱われますから、rm
コマンドで削除でき、mv
コマンドで名前を変更したり移動させたりできます。ハードリンクは、ターゲットと同じinodeを指していますから、リンクを壊すことなく移動させられます。
シンボリックリンク
シンボリックリンクを作成する
ln
コマンドに -s
オプションを指定すると、シンボリックリンクを作成できます。例えば次のように実行します。
$ ln -s /home/carol/target.txt /home/carol/Documents/softlink
このコマンドは、/home/carol/
ディレクトリにある target.txt
ファイルを指し示す、softlink
という名前のシンボリックリンクを /home/carol/Documents/
ディレクトリ内に作成します。(訳注:カレントディレクトリ以外にシンボリックリンクを作成する場合、TARGETをフルパスで指定するのが原則です。理由は後で説明しています。)
ハードリンクを作成するときと同様に、第二引数を省略すると、パス名を除いたターゲットと同じ名前のリンクをカレントディレクトリに作成します。
シンボリックリンクを管理する
シンボリックリンクはファイルシステム内のパスを指し示します。ファイルだけでなくディレクトリを指し示すシンボリックリンクを作成できますし、別のファイルシステムのファイルを指し示すこともできます。ls
コマンドの出力でシンボリックリンクはすぐにそれとわかります。
$ ls -lh total 112K -rw-r--r-- 1 carol carol 110K Jun 7 10:13 target.txt lrwxrwxrwx 1 carol carol 12 Jun 7 10:14 softlink -> target.txt
上の例では、softlink
ファイルのパーミッションの最初の文字が l
なので、シンボリックリンクだとわかります。さらに、ターゲット(target.txt
)を指していることが、ファイル名の後に矢印(->
)で示されています。
ls -l
の実行結果で、シンボリックリンク自体のパーミッションは所有者・所有グループ・その他とも常に rwx
になりますが、実際にアクセスできるかどうかはターゲットのパーミッションによって決まります。
シンボリックリンクを移動(削除)する
ハードリンクと同様に、シンボリックリンクも rm
コマンドで削除して、mv
コマンドで名前を変更したり移動させたりできます。ただし、シンボリックリンクを移動させる際には、リンクが壊れてしまわないように注意する必要があります。
シンボリックリンクを作成するときにターゲットの場所をフルパスで指定しなければ、シンボリックリンクが置かれたディレクトリからの 相対的な パスだと解釈されます。そのため、シンボリックリンクないしターゲットを移動させると、リンクが壊れてしまいます。
具体的な例で考えましょう。original.txt
という名前のファイルがカレントディレクトリにあります。次のコマンドを実行して、softlink
という名前のシンボリックリンクを作成します。
$ ln -s original.txt softlink
ここまでは何も問題ありませんね。ls
コマンドで確認します。
$ ls -lh total 112K -r--r--r-- 1 carol carol 110K Jun 7 10:13 original.txt lrwxrwxrwx 1 carol carol 12 Jun 7 19:23 softlink -> original.txt
矢印(->
)で示されているように、softlink
が original.txt
を指しています。このリンクを一つ上の階層(親ディレクトリ)に移動させ、そのリンクが指す内容を less
コマンドで表示させようとすると、以下のようなエラーになります。
$ mv softlink ../ $ less ../softlink ../softlink: No such file or directory
original.txt
のフルパスを指定していなかったため、リンクと同じディレクトリにある original.txt
を指すリンクを作成していたのです。softlink
を一つ上の階層(親ディレクトリ)に移動させたので、リンクと同じディレクトリに original.txt
ファイルはもはや存在しません。だからリンクが壊れてエラーになったのです。
移動させたときにリンクが壊れてしまわないようにするには、ターゲットをフルパスで指定します。
$ ln -s /home/carol/Documents/original.txt softlink
このようにターゲットのフルパスを指定して作成すると、シンボリックリンクをどこに移動させても壊れずにターゲットを指し続けます。(訳注:最初の例でTARGETをフルパスで指定した理由も同じです。ここでは説明のためにカレントディレクトリに作成したリンクをわざわざ移動させてリンクが壊れることを示しましたが、シンボリックリンクの指し先が それが置かれたディレクトリからの相対パス として解釈されることに注意すれば、相対パスで指定しても構いません。)
ls
コマンドで確かめてみます。
$ ls -lh total 112K lrwxrwxrwx 1 carol carol 40 Jun 7 19:34 softlink -> /home/carol/Documents/original.txt
演習
-
/home/carol/Documents
ディレクトリ内にdocument.txt
という名前のファイルがあります。このファイルへのシンボリックリンクをtext.txt
という名前でカレントディレクトリに作成してください。(訳注:カレントディレクトリがどこであるか明示されていないことに注意してください)。 -
あるファイルのハードリンクを作成することとコピーを作成することとはどう違いますか?
発展演習
-
以下に示すコマンドを実行して、
recipes.txt
という名前のファイルを作成し、このファイルのハードリンク(receitas.txt
)を作成して、そのハードリンクのシンボリックリンク(rezepte.txt
)を作成します。$ touch recipes.txt $ ln recipes.txt receitas.txt $ ln -s receitas.txt rezepte.txt
このディレクトリの内容は次のようになるはずです。
$ ls -lhi total 160K 5388833 -rw-r--r-- 4 carol carol 77K jun 17 17:25 receitas.txt 5388833 -rw-r--r-- 4 carol carol 0K jun 17 17:25 recipes.txt 5388837 lrwxrwxrwx 1 carol carol 12 jun 17 17:25 rezepte.txt -> receitas.txt
ハードリンクの
receitas.txt
はrecipes.txt
と同じinodeを指します。receitas.txt
を削除すると、シンボリックリンクのrezepte.txt
はどうなりますか? 理由とともに答えてください。 -
フラッシュドライブを差し込み、
/media/youruser/FlashA
にマウントしました。そのフラッシュドライブの一番上の階層にあるesquema.pdf
というファイルを指し示す、schematics.pdf
という名前のリンクをホームディレクトリに作ろうとして、以下のコマンドを実行しました。$ ln /media/youruser/FlashA/esquema.pdf ~/schematics.pdf
このコマンドを実行するとどうなるでしょうか? 理由とともに答えてください。
-
ls -lah
を実行すると、以下のように出力されました。$ ls -lah total 3,1M drwxr-xr-x 2 carol carol 4,0K jun 17 17:27 . drwxr-xr-x 5 carol carol 4,0K jun 17 17:29 .. -rw-rw-r-- 1 carol carol 2,8M jun 17 15:45 compressed.zip -rw-r--r-- 4 carol carol 77K jun 17 17:25 document.txt -rw-rw-r-- 1 carol carol 216K jun 17 17:25 image.png -rw-r--r-- 4 carol carol 77K jun 17 17:25 text.txt
-
上記の出力からわかるのはシンボリックリンクの数ですか、それともハードリンクの数ですか?
-
各ファイルのinodeを確認するには、
ls
コマンドにどのオプションを指定しますか?
-
-
~/Documents
ディレクトリ内に、顧客名が書かれたclients.txt
という名前のファイルと、somedir
という名前のディレクトリがあります。somedir
ディレクトリ内に、ファイル名は同じくclients.txt
ですが別の顧客名が書かれた別のファイルがあります。以下のコマンドを実行すると、この状況を再現できます。$ cd ~/Documents $ echo "John, Michael, Bob" > clients.txt $ mkdir somedir $ echo "Bill, Luke, Karl" > somedir/clients.txt
以下のコマンドを実行して、
somedir
ディレクトリ内に、clients.txt
ファイルを指し示すpartners.txt
という名前のリンクを作成します。$ cd somedir/ $ ln -s clients.txt partners.txt
ここまでのところのディレクトリ構造は以下のようになります。
Documents |-- clients.txt `-- somedir |-- clients.txt `-- partners.txt -> clients.txt
次に、以下のコマンドを実行して、
partners.txt
を、somedir
ディレクトリから、~/Documents
ディレクトリに移動させます。そして、less
コマンドでpartners.txt
の内容を表示します。$ cd ~/Documents/ $ mv somedir/partners.txt . $ less partners.txt
このリンクは機能するでしょうか? もし機能するなら、どのファイルを指し示しているでしょうか? 理由とともに答えてください。
-
以下は
ls -l
の実行結果の抜粋です。-rw-r--r-- 1 carol carol 19 Jun 24 11:12 clients.txt lrwxrwxrwx 1 carol carol 11 Jun 24 11:13 partners.txt -> clients.txt
partners.txt
のパーミッションは何ですか? 理由とともに答えてください。
まとめ
このレッスンでは、次のことを学びました。
-
リンクとは何か。
-
シンボリック リンクと ハード リンクはどう違うか。
-
どのようにリンクを作成するか。
-
どのようにリンクを移動(名前の変更、削除)するか。
このレッスンでは、次のコマンドについて説明しました。
-
ln
: リンクを作成するコマンドです。オプションなしではハードリンクを作成します。-s
オプションを指定するとシンボリックリンクを作成します。ハードリンクはターゲットと同じファイルシステム内にしか作成できません。シンボリックリンクはターゲットと別のファイルシステムにも作成できます(ネットワークストレージに作成することもできます)。 -
ls
コマンドに-i
オプションを指定すると、inodeを表示します。
演習の解答
-
/home/carol/Documents
ディレクトリ内にdocument.txt
という名前のファイルがあります。このファイルへのシンボリックリンクをtext.txt
という名前でカレントディレクトリに作成してください。(訳注:カレントディレクトリがどこであるか明示されていないことに注意してください)。シンボリックリンクを作成するコマンドは
ln -s
です。シンボリックリンクがどのディレクトリにあっても機能するように、ターゲットをフルパスで指定します。実行するコマンドは次のとおりです。$ ln -s /home/carol/Documents/document.txt text.txt
-
あるファイルのハードリンクを作成することとコピーを作成することとはどう違いますか?
ハードリンクはファイルの別名です。ハードリンクは元ファイルの複製のように見えますが、どちらもディスク上の同じデータを指していますから、同一の実体です。ハードリンクの内容を変更したら元ファイルの内容も変更されますし、元ファイルの内容を変更したらハードリンクの内容も変更されます。ファイルのコピーは、ディスク上の別の場所にある全く別の実体です。コピーの内容を変更しても元ファイルの内容は変更されませんし、元ファイルの内容を変更してもコピーの内容は変更されません。
発展演習の解答
-
以下に示すコマンドを実行して、
recipes.txt
という名前のファイルを作成し、このファイルのハードリンク(receitas.txt
)を作成して、そのハードリンクのシンボリックリンク(rezepte.txt
)を作成します。$ touch recipes.txt $ ln recipes.txt receitas.txt $ ln -s receitas.txt rezepte.txt
このディレクトリの内容は次のようになるはずです。
$ ls -lhi total 160K 5388833 -rw-r--r-- 4 carol carol 77K jun 17 17:25 receitas.txt 5388833 -rw-r--r-- 4 carol carol 0K jun 17 17:25 recipes.txt 5388837 lrwxrwxrwx 1 carol carol 12 jun 17 17:25 rezepte.txt -> receitas.txt
ハードリンクの
receitas.txt
はrecipes.txt
と同じinodeを指します。receitas.txt
を削除すると、シンボリックリンクのrezepte.txt
はどうなりますか? 理由とともに答えてください。シンボリックリンクの
rezepte.txt
は機能しなくなります。シンボリックリンクは、inodeではなく名前を指し示すからです。データは存在していてrecipes.txt
という名前でアクセスできるのですが、rezepte.txt
が指し示すreceitas.txt
という名前はもう存在しないので機能しなくなります。 -
フラッシュドライブを差し込み、
/media/youruser/FlashA
にマウントしました。そのフラッシュドライブの一番上の階層にあるesquema.pdf
というファイルを指し示す、schematics.pdf
という名前のリンクをホームディレクトリに作ろうとして、以下のコマンドを実行しました。$ ln /media/youruser/FlashA/esquema.pdf ~/schematics.pdf
このコマンドを実行するとどうなるでしょうか? 理由とともに答えてください。
コマンドの実行に失敗し、
Invalid cross-device link(無効なクロスデバイスリンクです)
というエラーメッセージが表示されます。このメッセージに示されているように、ハードリンクは異なるファイルシステム(パーティションやデバイス)にあるファイルを指し示すことができません。異なるファイルシステムにあるファイルを指し示すリンクを作成する場合は、ln
コマンドに-s
オプションを指定して シンボリック リンクを作成します。 -
ls -lah
を実行すると、以下のように出力されました。$ ls -lah total 3,1M drwxr-xr-x 2 carol carol 4,0K jun 17 17:27 . drwxr-xr-x 5 carol carol 4,0K jun 17 17:29 .. -rw-rw-r-- 1 carol carol 2,8M jun 17 15:45 compressed.zip -rw-r--r-- 4 carol carol 77K jun 17 17:25 document.txt -rw-rw-r-- 1 carol carol 216K jun 17 17:25 image.png -rw-r--r-- 4 carol carol 77K jun 17 17:25 text.txt
-
上記の出力からわかるのはシンボリックリンクの数ですか、それともハードリンクの数ですか?
ハードリンクの数です(パーミッションの直後に表示されています)。シンボリックリンクを作成しても、
ls -l
の出力からわかるリンク数は増えません。 -
各ファイルのinodeを確認するには、
ls
コマンドにどのオプションを指定しますか?-i
オプションを指定します。以下のように、ls
の出力の最初の列にinode番号が表示されます。$ ls -lahi total 3,1M 5388773 drwxr-xr-x 2 carol carol 4,0K jun 17 17:27 . 5245554 drwxr-xr-x 5 carol carol 4,0K jun 17 17:29 .. 5388840 -rw-rw-r-- 1 carol carol 2,8M jun 17 15:45 compressed.zip 5388833 -rw-r--r-- 4 carol carol 77K jun 17 17:25 document.txt 5388837 -rw-rw-r-- 1 carol carol 216K jun 17 17:25 image.png 5388833 -rw-r--r-- 4 carol carol 77K jun 17 17:25 text.txt
-
-
~/Documents
ディレクトリ内に、顧客名が書かれたclients.txt
という名前のファイルと、somedir
という名前のディレクトリがあります。somedir
ディレクトリ内に、ファイル名は同じくclients.txt
ですが別の顧客名が書かれた別のファイルがあります。以下のコマンドを実行すると、この状況を再現できます。$ cd ~/Documents $ echo "John, Michael, Bob" > clients.txt $ mkdir somedir $ echo "Bill, Luke, Karl" > somedir/clients.txt
以下のコマンドを実行して、
somedir
ディレクトリ内に、clients.txt
ファイルを指し示すpartners.txt
という名前のリンクを作成します。$ cd somedir/ $ ln -s clients.txt partners.txt
ここまでのところのディレクトリ構造は以下のようになります。
Documents |-- clients.txt `-- somedir |-- clients.txt `-- partners.txt -> clients.txt
次に、以下のコマンドを実行して、
partners.txt
を、somedir
ディレクトリから、~/Documents
ディレクトリに移動させます。そして、less
コマンドでpartners.txt
の内容を表示します。$ cd ~/Documents/ $ mv somedir/partners.txt . $ less partners.txt
このリンクは機能するでしょうか? もし機能するなら、どのファイルを指し示しているでしょうか? 理由とともに答えてください。
これは紛らわしい状況です。リンクは機能し、
~/Documents
ディレクトリ内のclients.txt
ファイルを指し示します。John
、Michael
、Bob
という名前が書かれているほうのファイルです。シンボリックリンク
partners.txt
を作成する際に、ターゲットであるclients.txt
のフルパスを指定しなかったので、リンクがあるディレクトリからの相対的なパスだと解釈されます。本問では、ターゲットが、partners.txt
リンクと同じディレクトリにあると解釈されます。そのリンクが、
~/Documents/somedir
ディレクトリから~/Documents
ディレクトリに移動され、ターゲットがリンクと同じディレクトリに存在しなくなるので、リンクが壊れて機能しなくなるはずです。しかし、偶然にも~/Documents
ディレクトリ内にclients.txt
という名前のファイルが存在するため、リンクはこのファイルを指し示すようになります。somedir
ディレクトリ内のclients.txt
ファイルではありません。こうしたややこしい状況を避けるために、シンボリックリンクを作成する際には、ターゲットのフルパスを指定するようにするとよいです。
-
以下は
ls -l
の実行結果の抜粋です。-rw-r--r-- 1 carol carol 19 Jun 24 11:12 clients.txt lrwxrwxrwx 1 carol carol 11 Jun 24 11:13 partners.txt -> clients.txt
partners.txt
のパーミッションは何ですか? 理由とともに答えてください。partners.txt
のパーミッションはrw-r--r--
です。リンクのパーミッションはターゲットのパーミッションと常に同じです。