トップ > Linuxらしい使い方を覚える >
ハードリンク・シンボリックリンクでファイルを別名でも参照

  

ファイルやディレクトリを別名でも参照できるようにしよう

前の記事に続き、ファイルやディレクトリに関する話題です。 この記事では "ハードリンク" と "シンボリックリンク" について解説します。

ハードリンクもシンボリックリンクも、どちらもファイルやディレクトリを別名で参照できるようにするための仕組みです。

ハードリンクまたはシンボリックリンクの仕組みを使うことで、例えば、

/home/taro/Diary.txt

というファイルを、

/home/taro/Nikki.txt

や、

/home/taro/Documents/Diary.txt

のようなファイルパスでも参照することができます。

ハードリンクとシンボリックリンクの違い

ハードリンクとシンボリックリンクには、もちろん違いがあります。 では、その違いとは何なのでしょうか。

ハードリンク

ハードリンクというのは、同じファイルに複数の名前を付けるようなものです。 紙での作業に例えれば、

  1. 新たなノートを用意して "Diary" というシールを貼る
  2. 同じノートに "Nikki" というシールをさらに貼る

というようなことです。 このノートは "Diary" でもあり "Nikki" でもあります。

  
ハードリンクはディレクトリには使えません。

シンボリックリンク

一方、シンボリックリンクは同じファイルに複数の名前を付けるようなものではなく、いわゆる "別紙参照" のような仕組みです。 紙での作業に例えれば、

  1. 新たなノートを用意して "Diary" というシールを貼る
  2. 別の表紙だけのノートも用意して "Nikki" というシールを貼る
  3. 表紙だけのノートに "Diaryを参照" というメモを挟む

となるでしょうか。

  
シンボリックリンクはファイルにもディレクトリにも使えます。

ハードリンクとシンボリックリンクを使ってみよう

では、実際にハードリンクとシンボリックリンクを使ってみましょう。 ホームディレクトリに、

/home/taro/Diary.txt

というファイルを作成し、そのファイルに、

/home/taro/Nikki.txt

という別名を与えます。 ハードリンクとシンボリックリンクのそれぞれの仕組みでやってみます。

まずは、Diary.txt を作成しましょう。 端末を開き、キーボードから echo 'It was rainy today.' > Diary.txt と入力して、Enterキーを押してください。


echo 'It was rainy today.' >  Diary.txt

 

以下のようにファイル Diary.txt を作成します。

taro@myhostname:~$ echo 'It was rainy today.' >  Diary.txt
taro@myhostname:~$

ファイルの中身を確認しておきましょう。 キーボードから cat Diary.txt と入力して、Enterキーを押してください。


cat Diary.txt

 

以下のようにファイル Diary.txt の内容が表示されます。

taro@myhostname:~$ cat Diary.txt
It was rainy today.
taro@myhostname:~$

ファイルの詳細情報も見ておきましょう。 キーボードから ls -l Diary.txt と入力して、Enterキーを押してください。


ls -l Diary.txt

 

以下のようにファイル Diary.txt の詳細情報が表示されます。 ハードリンク数(パーミッションと所有者の間)が 1 であることを覚えておいてください。

taro@myhostname:~$ ls -l Diary.txt
-rw-rw-r-- 1 taro taro 20  6月 26 11:14 Diary.txt
taro@myhostname:~$

これでファイル Diary.txt の準備ができました。


では、このファイル Diary.txt に Nikki.txt という別名を与えましょう。 まずは、ハードリンクでやってみます。

ハードリンクを作成するためのコマンドは ln コマンドです。 キーボードから ln Diary.txt Nikki.txt と入力して、Enterキーを押してください。


ln Diary.txt Nikki.txt

 
  
"LiNk" から連想して覚えましょう。

以下のように見た目には何も起こりません。

taro@myhostname:~$ ln Diary.txt Nikki.txt
taro@myhostname:~$

では、Diary.txt と Nikki.txt の詳細情報を確認してみましょう。 キーボードから ls -l Diary.txt Nikki.txt と入力して、Enterキーを押してください。


ls -l Diary.txt Nikki.txt

 

以下のように2つのファイルの詳細情報が表示されます。 ファイル名以外の情報が全て同じになっています

taro@myhostname:~$ ls -l Diary.txt Nikki.txt
-rw-rw-r-- 2 taro taro 20  6月 26 11:14 Diary.txt
-rw-rw-r-- 2 taro taro 20  6月 26 11:14 Nikki.txt
taro@myhostname:~$

注目すべきは、ハードリンク数が 2 になっている点です。 1つのファイルに2つ目のファイル名が与えられたため、ハードリンク数が 2 になりました。 同じノートに2枚のシールが貼られているということです。

ファイル Nikki.txt の中身を確認しておきましょう。 キーボードから cat Nikki.txt と入力して、Enterキーを押してください。


cat Nikki.txt

 

以下のようにファイル Nikki.txt の内容が表示されます。 Diary.txt と同じ内容であることが確認できました。

taro@myhostname:~$ cat Nikki.txt
It was rainy today.
taro@myhostname:~$

ではここで、Nikki.txt の内容を変更してみましょう。 端末を開き、キーボードから echo 'It was sunny today.' > Nikki.txt と入力して、Enterキーを押してください。


echo 'It was sunny today.' >  Nikki.txt

 

以下のようにファイル Nikki.txt を上書きします。

taro@myhostname:~$ echo 'It was sunny today.' >  Nikki.txt
taro@myhostname:~$

さあ、ファイル Diary.txt 中身はどうなっているでしょうか。 キーボードから cat Diary.txt と入力して、Enterキーを押してください。


cat Diary.txt

 

以下のようにファイル Diary.txt の内容が表示されます。 期待通り変更されています。

taro@myhostname:~$ cat Diary.txt
It was sunny today.
taro@myhostname:~$

ファイル Diary.txt と Nikki.txt は同じ内容を持つファイルですから当然の結果です。

ではここで、ファイル Diary.txt を削除してみましょう。 紙での作業に例えるなら、ノートに貼られた "Diary" というシールを剥がす作業です。 キーボードから rm Diary.txt と入力して、Enterキーを押してください。


rm Diary.txt

 

以下のように何のメッセージも表示されません。 つまり、ファイル Diary.txt の削除は成功しました。

taro@myhostname:~$ rm Diary.txt
taro@myhostname:~$

では、ファイル Nikki.txt の中身を確認しておきましょう。 ファイル Diary.txt が削除されたことで何か変化があったでしょうか。 キーボードから cat Nikki.txt と入力して、Enterキーを押してください。


cat Nikki.txt

 

以下のようにファイル Nikki.txt の内容が表示されます。 ファイル Diary.txt が削除されても中身は残っていました。

taro@myhostname:~$ cat Nikki.txt
It was sunny today.
taro@myhostname:~$

ファイル Nikki.txt の詳細情報も見ておきましょう。 キーボードから ls -l Nikki.txt と入力して、Enterキーを押してください。


ls -l Nikki.txt

 

以下のようにファイル Nikki.txt の詳細情報が表示されます。 ハードリンク数(パーミッションと所有者の間)が 1 に戻っています。

taro@myhostname:~$ ls -l Nikki.txt
-rw-rw-r-- 1 taro taro 20  6月 26 11:18 Nikki.txt
taro@myhostname:~$

紙での作業に例えると、ノートに貼られているシールは "Nikki" だけです。 よって、ハードリンク数は 1 に戻りました。

ハードリンクの説明はこれで終わりです。 シンボリックリンクの説明に進む前に、Nikki.txt を Diary.txt に改名しておきましょう。 キーボードから mv Nikki.txt Diary.txt と入力して、Enterキーを押してください。


mv Nikki.txt Diary.txt

 

以下のように Nikki.txt を Diary.txt に改名します。

taro@myhostname:~$ mv Nikki.txt Diary.txt
taro@myhostname:~$

では次に、シンボリックリンクを使って別名を与えてみましょう。 ファイル Diary.txt に Nikki.txt という別名を与えます。 キーボードから ln -s Diary.txt Nikki.txt と入力して、Enterキーを押してください。


ln -s Diary.txt Nikki.txt

 
  
シンボリックリンクの作成にも ln コマンドを使います。 -s オプションを付けることでシンボリックリンクが作成されます。

以下のように見た目には何の変化もありません。

taro@myhostname:~$ ln -s Diary.txt Nikki.txt
taro@myhostname:~$

では、Diary.txt と Nikki.txt の詳細情報を確認してみましょう。 キーボードから ls -l Diary.txt Nikki.txt と入力して、Enterキーを押してください。


ls -l Diary.txt Nikki.txt

 

以下のように2つのファイルの詳細情報が表示されます。 注目すべき点が3つほどあります

taro@myhostname:~$ ls -l Diary.txt Nikki.txt
-rw-rw-r-- 1 taro taro 20  6月 26 11:18 Diary.txt
lrwxrwxrwx 1 taro taro  9  6月 26 11:21 Nikki.txt -> Diary.txt
taro@myhostname:~$

注目すべき点の1つ目は、ファイル Nikki.txt の1列目の先頭文字(ファイル種別)が l(エル) になっていることです。 l(エル) はシンボリックリンクであることを示しています。

2つ目は、ファイル Nikki.txt のファイル名の後ろに -> Diary.txt と表示されていることです。 みなさんの予想通り、これは "Diary.txt" へリンクが張られていることを示しています。

3つ目の注目点は、ファイル Diary.txt も Nikki.txt もハードリンクが 1 であるということです。 紙での作業に例えると、ノートは2冊あります。 どちらのノートにもシールは1枚しか貼られていません。 よって、ハードリンク数は 1 というわけです。

ファイル Nikki.txt の中身を確認しておきましょう。 キーボードから cat Nikki.txt と入力して、Enterキーを押してください。


cat Nikki.txt

 

以下のようにファイル Nikki.txt の内容が表示されます。 Diary.txt と同じ内容であることが確認できました。

taro@myhostname:~$ cat Nikki.txt
It was sunny today.
taro@myhostname:~$

ではここで、Nikki.txt の内容を変更してみましょう。 端末を開き、キーボードから echo 'It was windy today.' > Nikki.txt と入力して、Enterキーを押してください。


echo 'It was windy today.' >  Nikki.txt

 

以下のようにファイル Nikki.txt を上書きします。

taro@myhostname:~$ echo 'It was windy today.' >  Nikki.txt
taro@myhostname:~$

さて、ファイル Diary.txt 中身はどうなっているでしょう。 キーボードから cat Diary.txt と入力して、Enterキーを押してください。


cat Diary.txt

 

以下のようにファイル Diary.txt の内容が表示されます。 予想通り変更されています。

taro@myhostname:~$ cat Diary.txt
It was windy today.
taro@myhostname:~$

このようにシンボリックリンクでもファイルに別名を与えることができます。

ではここで、ファイル Diary.txt を削除してみましょう。 キーボードから rm Diary.txt と入力して、Enterキーを押してください。


rm Diary.txt

 

以下のように何のメッセージも表示されません。 つまり、ファイル Diary.txt の削除は成功しています。

taro@myhostname:~$ rm Diary.txt
taro@myhostname:~$

では、ファイル Nikki.txt の中身を確認してみましょう。 キーボードから cat Nikki.txt と入力して、Enterキーを押してください。


cat Nikki.txt

 

以下のようにエラーが発生します。 リンク先の実体ファイル Diary.txt が削除されましたから当然こうなります。

taro@myhostname:~$ cat Nikki.txt
cat: Nikki.txt: そのようなファイルやディレクトリはありません
taro@myhostname:~$

簡単に言えば、リンク切れの状態です。 今回の例では実体ファイルを削除しましたが、実体ファイルが移動された場合も同じくリンク切れになります。

後始末として、シンボリックリンク Nikki.txt を削除しましょう。 キーボードから rm Nikki.txt と入力して、Enterキーを押してください。


rm Nikki.txt

 

以下のように何のメッセージも表示されません。 つまり、シンボリックリンク Nikki.txt の削除は成功しました。 これで元通りです。

taro@myhostname:~$ rm Nikki.txt
taro@myhostname:~$
  

シンボリックリンクの複製(コピー)には注意が必要

シンボリックリンクを使う場合には、"リンク切れ" 以外にも注意しなければならないことがあります。 それが、複製の対象にシンボリックリンクが含まれる場合の挙動です。

簡単に言えば、シンボリックリンクをシンボリックリンクとして複製するのか、実体ファイルの中身を複製するのか、という点です。

例えば、以下のようにファイル Diary.txt とシンボリックリンク Nikki.txt を作成したとします。

taro@myhostname:~$ echo 'It was snowy today.' >  Diary.txt
taro@myhostname:~$ ln -s Diary.txt Nikki.txt
taro@myhostname:~$

Nikki.txt がシンボリックリンクで、実体ファイルが Diary.txt です。

このシンボリックリンク Nikki.txt を Copied.txt に複製してみます。 その際に何もオプションを付けずに以下のように実行したとします。

taro@myhostname:~$ cp Nikki.txt Copied.txt
taro@myhostname:~$

この場合、複製先である Copied.txt は以下のようになります。

taro@myhostname:~$ ls -l Copied.txt
-rw-rw-r-- 1 taro taro 20  6月 26 11:42 Copied.txt
taro@myhostname:~$

このように、通常ファイルとして複製されていることがわかります。 一応、以下のように中身も見ておきましょう。

taro@myhostname:~$ cat Copied.txt
It was snowy today.
taro@myhostname:~$

中身はきちんと複製されています。 つまり、シンボリックリンクではなく実体ファイルの中身が複製されたことがわかります。


では、シンボリックリンクをシンボリックリンクとして複製するにはどうすればいいのでしょうか。

cp コマンドにはそのためのオプション -d が用意されています。 以下のようにオプション -d を付けて実行することで、シンボリックリンクがシンボリックリンクとして複製されます。

taro@myhostname:~$ rm Copied.txt
taro@myhostname:~$ cp -d Nikki.txt Copied.txt

では、複製先である Copied.txt のファイル種別および内容を以下のように確認してみます。

taro@myhostname:~$ ls -l Copied.txt
lrwxrwxrwx 1 taro taro 9  6月 26 11:53 Copied.txt -> Diary.txt
taro@myhostname:~$ cat Copied.txt
It was snowy today.
taro@myhostname:~$

このように、シンボリックリンクとして複製されており、また、内容も正しいことがわかります。

cp コマンドのオプションについて

cp コマンドで知っておくべきオプションを以下に掲載します。

オプション 説明
-p ファイルの属性(所有者やアクセス権や最終変更日時など)を複製元と合わせる
-R 特殊なファイルは特殊な状態を維持する
ディレクトリの場合は中身をたどって複製する
-d シンボリックリンクはシンボリックリンクとして複製する
-a -pRd と同じ

cp コマンドを利用する場合には常に -a オプションを指定しておくのがいいでしょう。 可能な限り、複製元の状態を維持したままの複製が行われます。

複製元がファイルかディレクトリかを気にする必要はありません。 cp コマンドが上手に処理してくれます。

ファイルの種類が、通常ファイル・ハードリンク・シンボリックリンクのどれであるかも気にする必要はありません。 それも cp コマンドが上手く考えてくれます。

オプション -a では対応できない状況になった時に cp コマンドのマニュアルを参照して必要なオプションを探せばいいでしょう。

  

まとめ

ハードリンクやシンボリックリンクの仕組みを使うことで、ファイルやディレクトリに別名を与えることができます。 ハードリンクならば複数のファイルが同じファイル内容を持つことができ、どれも対等な関係になります。 なお、ハードリンクはディレクトリには使えません。

シンボリックリンクでは実体ファイルは1つだけであり、別名ファイルは実体ファイルへリンクを張っているにすぎません。 実体ファイルが消されたり、移動されると別名ファイルは役に立たなくなります。

操作/コマンド 説明
ln basename newname ハードリンクで basename に newname という別名を与える
ln -s basename newname シンボリックリンクで basename に newname という別名を与える

シンボリックリンクをシンボリックリンクとして複製したい場合は cp コマンドに -a オプションを指定しましょう。

メニュー