1. ホーム
  2. コース一覧
  3. LinuC Level1 v10.0 対策コース(パート1)
  4. リンクの仕組み

中級

LinuC Level1 v10.0 対策コース(パート1)

LinuC Level1 v10.0 対策コース(パート1)22/39

リンクの仕組み

こちらの記事では、Linuxにおけるリンクの仕組みについて解説します。

OSにはファイルやディレクトリに別名をつけ、異なる名前で同一ファイルにアクセスする仕組みが備わっています。Linuxでは二種類の方法があります。

inode

Linuxにおけるリンクを理解するには、inodeについて知っておく必要があります。Linuxでは全てのファイル・ディレクトリにinodeと呼ばれる一意の番号が割り振られます。全てのファイル・ディレクトリに対応するinode番号が存在しており、ファイル・ディレクトリに関する属性情報が格納されています。格納されている情報には以下のものがあります。

  • ファイル種別
  • ファイルサイズ
  • 所有者
  • アクセス権
  • リンク
  • ブロック番号

inode番号を確認するには-iオプションを使用したls -liコマンドを実行しましょう。

ls -li
total 0
283766 -rw-r--r-- 1 envader envader    0  427 10:33 test.txt

inode番号は一番初めの数字を指します。test.txtのinode番号は「283766」であり、「-rw-r--r--」の右隣にある「1」はリンク数を表しています。

ハードリンク

作成されたファイル・ディレクトリは、必ず一つ以上のinodeとつながることになります。この繋がりのことをハードリンクと呼びます。

ファイルの実体が一つであっても、その実体を参照するファイルが複数あれば、それぞれのファイル名で同一の実体を参照することができます。複数のハードリンクが存在している場合は参照しているinodeが同じなので、一方に変更を加えた時点でもう一方にも変化が反映されます。削除をする際にも、ハードリンクで繋がる全てのファイルを削除しない限りファイルの実体が消えることはありません。

ハードリンクの数を確認する時は、-iオプションを使用したls -liコマンドを実行しましょう。

ls -li
total 0
283746 -rw-r--r-- 3 envader envader 0  427 10:52 test.txt
283746 -rw-r--r-- 3 envader envader 0  427 10:52 test2.txt
283746 -rw-r--r-- 3 envader envader 0  427 10:52 test3.txt

上記の例では、1つのファイルとそのファイルへの2つのハードリンクがあるため、リンク数が「3」になっています。このリンク数「3」が「0」になった時、ファイルの実体は完全に消去されるということになります。また、inode番号も同じ「283746」となっている点をご確認ください。

ハードリンクはリンク先のファイルが存在するファイルシステムと異なるファイルシステム上に作成はできません。また、ディレクトリに対して作成することはできないのでご注意ください。

シンボリックリンク

シンボリックリンクはソフトリンクとも呼ばれ、その名の通り緩やかなリンクとなります。シンボリックリンクが指し示すのはリンク元の場所(ポインタ)であり、リンクを残したままファイルを削除するとリンク先を参照できなくなるのでエラーが発生します。別のファイルシステムへのリンクが作成可能で、ディレクトリへのリンクの作成も可能という点でもハードリンクと異なります。似たような仕組みにWindowsの「ショートカット」、Macの「エイリアス」などがあります。

シンボリックリンクの利点の一つはコンピューターへの負荷が少なくて済むことです。ファイルの複製ではなく、実体を伴わないまま別領域に保存された領域にアクセスできるシステムなので、トータルのファイルサイズを増やさずに作業を行うことができます。

シンボリックリンクを確認したい時は-iオプションを使用したls -liコマンドを実行しましょう。シンボリックリンクはパーミッションの1桁目のファイル種別が「l」に切り替わります。

ls -li
total 0
810844 lrwxrwxrwx 1 envader envader 8  427 12:30 synbol -> test.txt
811134 -rw-r--r-- 1 envader envader 0  427 12:30 test.txt

ハードリンクと違い、inode番号は重複していません。パーミッションの先頭につく「l」とファイル名の部分の「-> 」がシンボリックリンクであることを表しています。

ハードリンク・ソフトリンクの作成方法

リンクを作成するにはlnコマンドを使用します。オプションなしで使用すると自動的にハードリンクが作成されます。シンボリックリンクを作成するのであれば-sオプションを使用します。

ハードリンクの作成例

ln test.txt hard.txt

ls -li
total 0
811294 -rw-r--r-- 2 envader envader  0  427 12:41 hard.txt
811294 -rw-r--r-- 2 envader envader  0  427 12:41 test.txt

inode番号が同じなので、ハードリンクが作成されていることが分かります。

シンボリックリンクの作成例

ln -s test.txt symb.txt

ls -li
total 0
811451 lrwxrwxrwx 1 envader envader  8  427 12:45 symb.txt -> test.txt
811294 -rw-r--r-- 1 envader envader  0  427 12:41 test.txt

-sオプションをつけることによってシンボリックリンクが作成されています。

リンク先のファイルを削除した場合

rm test.txt

ls -li
total 0
1322082 lrwxrwxrwx 1 envader envader 8  428 10:06 symb.txt -> test.txt

cat symb.txt
cat: symb.txt: No such file or directory

リンク先のファイルを削除すると、リンクだけが残り中身を確認することもできません。再度新しいリンク先を作成することで再利用も可能です。

シンボリックリンクのcpとmv

まずはcpコマンドについて再確認します。cpコマンドは特定のファイル・ディレクトリをコピーするコマンドです。コピーされた際のinode番号を確認してみましょう。

cp test.txt test2.txt

ls -li
total 0
811558 -rw-r--r-- 1 envader envader  0  427 12:55 test.txt
811559 -rw-r--r-- 1 envader envader  0  427 12:55 test2.txt

inode番号が異なっています。cpコマンドの場合は新しく別の実体が作られているということになります。

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

cpコマンドでシンボリックリンクをコピーすると、デフォルトの状態ではリンク先のファイル内容がコピーされます。

cp symb.txt symb2.txt

ls -li
total 0
811410 lrwxrwxrwx 1 envader envader 8  427 13:01 symb.txt -> test.txt
811362 -rw-r--r-- 1 envader envader 0  427 13:02 symb2.txt
811558 -rw-r--r-- 1 envader envader 0  427 12:55 test.txt

オプションをつけていないので、test.txtのファイル内容がコピーされています。シンボリックリンク自体はコピーされていません。シンボリックリンク自体をコピーするには-dオプションをつける必要があります。

cp -d symb.txt symb2.txt

ls -li
total 0
811410 lrwxrwxrwx 1 envader envader 8  427 13:01 symb.txt -> test.txt
801948 lrwxrwxrwx 1 envader envader 8  427 13:07 symb2.txt -> test.txt
811558 -rw-r--r-- 1 envader envader 0  427 12:55 test.txt

このように、シンボリックリンクがコピーされました。

シンボリックリンクの移動

mvコマンドでファイルを移動してもinode番号が変わることはありません。ではmvコマンドでシンボリックリンク先のファイルを移動させるとどうなるでしょうか?test.txtdirディレクトリに移動させてみましょう。

ls -li
total 4
1322237 drwxr-xr-x 2 envader envader 4096  428 10:18 dir
1322082 lrwxrwxrwx 1 envader envader    8  428 10:06 symb.txt -> test.txt
1322210 -rw-r--r-- 1 envader envader    0  428 10:19 test.txt

mv test.txt dir

cat symb.txt
cat: symb.txt: No such file or directory

シンボリックリンクが参照しているのはファイル名であり、inode番号ではないため注意してください。シンボリックリンク自体をmvコマンドで別ディレクトリに移動しても同じ結果になります。また、mvコマンドでシンボリック名を変更したとしても、リンク先が変わることはありません。

バージョン管理

シンボリックリンクを利用することで、共有ライブラリなどのバージョン管理が可能になります。

/usr/lib$ ls -l
lrwxrwxrwx 1 root root   17  428 09:47 testlib.so -> testlib.so.18.0.0
-rwxr-xr-x 1 root root    0  428 09:42 testlib.so.18.0.0

testlib.soという共有ライブラリをアプリケーションから呼び出す場合、シンボリックリンクを利用して呼び出すことが多くなります。これは、バージョン管理の運用を考慮しているためです。

例えば、最新版の「18.0.1」に変更をする際、元の「18.0.0」はそのままにしておきます。

/usr/lib$ ls -l
lrwxrwxrwx 1 root root   17  428 09:47 testlib.so -> testlib.so.18.0.1
-rwxr-xr-x 1 root root    0  428 09:42 testlib.so.18.0.0
-rwxr-xr-x 1 root root    0  428 09:42 testlib.so.18.0.1

利用するプログラム側では特に変更はありません。もし新しいバージョンに不具合があったとしても、前のバージョンに戻すことで対応が可能になります。

まとめ

Linuxのリンクの仕組みについて解説しました。シンボリックリンクは応用が効く分、扱い方が少し難しいです。今回は主要なオプションのみの紹介になりましたが、他にもさまざまなオプションが存在するので是非調べてみてください。

記事の内容は理解できましたか?