Linuxのリンク
2018/04/22
今回はただの前置きです
  • 今回のレポートはWindowsのリンクの話をする前に準備としてLinuxのリンクを扱っています。Linuxのリンク理解されている方は読み飛ばして下さい。

Linux環境ではリンクを使うことが多い
  • リンクとは何かを簡単に言うと、ファイルやフォルダを別名で参照する機能です。このリンクという機能ですがLinux環境で作業をしていると頻繁に使用するため、Windowsでリンクの話をするきっかけのほとんどは、Linuxで使っているリンクをWindows上でも使いたいという要求からスタートします。

  • リンクをどんな時に使うかですが、例えば、あるプロジェクトで共通データとしてライブラリを参照しているとしましょう。メンバ全員が参照するライブラリはプロジェクト開始段階で安定版であって欲しいですが、大抵は頻繁に変更が入ります。例えばライブラリが下記の構成だとしましょう。
    /project_a/
       +--lib/
       |  `--lib_20180301a/ # 最初のライブラリ
    ライブラリを参照する各作業ファイルは下記のような記述を持っているでしょう。
    vcs -l job_00.log +libext+.v+.vp \
      -y /project_a/lib/lib_20180301a \
      ...
     
    vcs -l job_01.log +libext+.v+.vp \
      -y /project_a/lib/lib_20180301a \
      ...
      ......

  • ここでライブラリに変更が入ります。アップデートされて lib_20180316a になったとしましょう。
    /project_a/
       +--lib/
       |  +--lib_20180316a/ # 更新版ライブラリ
       |  `--lib_20180301a/ # 最初のライブラリ
    すると各作業ファイルも参照パスを全て変更しなければいけないのですが、これは面倒な上にミスを誘発してしまいますね。こんな時にリンクを使用します。例えば lib_updated/ を常にメンバに使用させたい最新版ライブラリを指し示すリンクとしたい場合、Linux環境下ではlnコマンドを使用します。
    $ cd /project_a/lib
    $ ln -s lib_20180316a lib_updated
        ↓結果
    /project_a/
       +--lib/
       |  +--lib_updated/ --> lib_20180316a/ へのシンボリックリンク
       |  +--lib_20180316a/ # 更新版ライブラリ
       |  `--lib_20180301a/ # 最初のライブラリ
    後は、各作業ファイルが常に lib_updated/ を参照するようにしておけば、ライブラリ側の変更は即座に全体へ反映されることになります。

ハードリンクとシンボリックリンク
  • Linuxのリンクの方法は二種類あります。ハードリンク(Hard Link)とシンボリックリンク(Symbolic/Soft Link)です。ハードリンクは普段ほとんど意識されていませんが、リンクを理解するには知っている方が都合良いので、まずハードリンクから説明したいと思います。

  • ハードリンク
    • 例えばあるディレクトリの下でファイルを2個(file000 と file001)作成したとします。ファイルリストを見ると下記のようになります。青字部分が「1」であることに注目して下さい。
      $ ls -l
      -rw-rw-r-- 1 altmo altmo 31 Apr 21 11:01 file000
      -rw-rw-r-- 1 altmo altmo 31 Apr 21 11:01 file001

    • 今の状態を図示すると、Figure 1のようになります。ファイル名(file_000 と file_001)とデータの実体がOSによって関連付けされています。このファイル名とデータ実体との関連付けをハードリンクと呼びます。普段我々はハードリンクをほとんど意識していませんが、あるデータの実体は最低でも一つのハードリンクを持つことになります。

      Figure 1: ファイル作成直後のファイル名とデータ実体の関係

    • Figure 1を見るとわかりますが、このハードリンクはプログラム言語で言うところのリファレンス(*1)に相当します。つまりハードリンクを作成するとは、データ実体を指す別名のリファレンスを追加することです。

      Figure 2: ハードリンクの追加作成

    • Linux上でハードリンク又はシンボリックリンクを作成するには ln コマンドを使用します。Figure 2のように、もともと file001 が指しているデータ実体へのハードリンク hl_file001 を追加する場合は下記となります。
      $ ln file001 hl_file001
      ここでファイルリストを見てみましょう。青字部分が「2」に変わっていますね。そうです。この数字はデータ実体へのハードリンクの数、つまりリファレンスカウントを意味しています。
      $ ls -l
      -rw-rw-r-- 1 altmo altmo 31 Apr 21 11:01 file000
      -rw-rw-r-- 2 altmo altmo 31 Apr 21 11:01 file001
      -rw-rw-r-- 2 altmo altmo 31 Apr 21 11:01 hl_file001
      仮に file001 を削除すると、hl_file001 が残って、このリファレンスカウントが 1 に減ります。OSはリファレンスカウントが 0 にならない限りデータ実体部を解放しないので、hl_file001 から見てデータは残り続けるわけです。

    • また、この仕組からハードリンクの制限として
      • 他のCPUが管理するデータにはハードリンクを作れない ... リファレンスカウントが不明だから
      • ディレクトリ/フォルダにはハードリンクを作れない ... データ実体ではなくただのラベルだから
      があることは、容易に推測/理解できるでしょう。

  • シンボリックリンク
    • シンボリックリンクはデータの実体ではなく、ファイル名やディレクトリ名などのシンボルにリンクを作成します。具体例として、ハードリンクで扱った file001 にシンボリックリンク sl_file001 を作成してみます。シンボリックリンクの作成では -s オプションを付けます。
      ln -s file001 sl_file001
      この状態でファイルリストを見ると下記のように、ファイル属性を示す先頭文字が l になっています。(*2)
      $ ls -l
      -rw-rw-r-- 1 altmo altmo 31 Apr 21 11:01 file000
      -rw-rw-r-- 2 altmo altmo 31 Apr 21 11:01 file001
      -rw-rw-r-- 2 altmo altmo 31 Apr 21 11:01 hl_file001
      lrwxrwxrwx 1 altmo altmo 7 Apr 22 13:14 sl_file001 -> file001


      Figure 3: シンボリックリンクとファイル名の関係

    • ここでシンボリックリンクのソースとなっている file001 を削除してみます。すると、シンボリックリンク sl_file001 は残っていますが、アクセスすると「ファイルが見つからない」というエラーになります。
      $ rm file001
      $ cat sl_file001
      cat: sl_file001: No such file or directory
      しかし、データの実体を指す hl_file001 は残っているため、データそのものは残っています。
      $ cat hl_file001
      [file001] Contents of file001.

    • 今の状態を図示すると、Figure 4のようになります。

      Figure 4: シンボリックリンクのソース削除

    • このようにシンボリックリンクは、文字通りファイルやディレクトリの名前にリンクしているので、元のファイルを削除する又はファイル名を変更すると、そのリンクが切れます。しかしファイルを削除した後、中身が全く別だったとしても同じ名前のファイルを置くと、シンボリックリンクは復活します。


次回はWindowsのリンク
  • Linuxのリンクの話はいかがだったでしょうか。特にシンボリックリンクは自由度が高いため、Linux環境ではデータ参照で便利に使用される傾向にあります。実はWindowsにも Windows Vista以降で似た機能が提供されています。次回はWindowsのリンクについて話をしたいと思います。
Notes
  • なのでFigure 1のhard linkに(reference)と書いています。
  • ls -F だと、シンボリックリンクの後に @ が付きます。sl_file001@ のように。
Copyright(C) 2018 Altmo
本HPについて