試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

ハードリンクとシンボリックリンクについて

端末上でディレクトリ内のファイルやディレクトリを一覧する作業について」や「ファイル/ディレクトリの基本的な操作を行うコマンドについて」の中で触れていたが説明を含んでいなかったため、ハードリンクとシンボリックリンクについてをここで扱っておく。

  1. ハードリンクとシンボリックリンク
  2. シンボリックリンク作成に関する幾つかのオプション指定について
  3. シンボリックリンクとパスの種類

ハードリンクとシンボリックリンク

ハードリンクというのは既に存在するファイルやディレクトリに別の名前を持たせて同一のファイルに複数のパス名*1でアクセスできるようにするもので、ln*2コマンドを用いて

$ ln [既存のファイルやディレクトリ] [新しいパス]

のようにして作成し、1つのハードリンクを作るとlsなどで表示される「リンク数」は2になる。異なるファイルシステムをまたぐリンクは仕様により作れない。*3
ディレクトリのリンク数は多く(子ディレクトリ数 + 2)表示されるが、これは自分自身を「.」としてハードリンクで参照するのと子ディレクトリから親を「..」としてハードリンクで参照するため。*4
lnコマンドに-sオプションを付けるとシンボリックリンクという種類のリンクになり、こちらはリンク先のパス(場所)に関する情報を保持したデータとなる。

(シンボリックリンクの出力先パスを指定する形)
$ ln -s [ファイルやディレクトリ] [シンボリックリンクの場所]
(リンク先のファイル/ディレクトリ名のままでリンクを任意のディレクトリに作成・保存ディレクトリが現在の作業ディレクトリの場合は省略可)
$ ln -s [ファイルやディレクトリ] [シンボリックリンクの保存ディレクトリ]

ハードリンクとは異なり、別のファイルシステム上に配置できるが、元のデータのパス情報が変わる(名前変更かディレクトリ移動を行う)と壊れたリンクとなってしまい参照できなくなる。その場合、新しいパスに対してリンクを作成し直す必要がある。元のデータを元の場所に戻しても有効なリンクに戻る。
また、シンボリックリンクは作成した時点で存在しないファイルやディレクトリに対して(壊れたリンクの状態で)作成することもできる。

シンボリックリンク作成に関する幾つかのオプション指定について

-fオプションは新しいリンクのパスが既に存在している場合にこれを上書きする。
-nオプションはディレクトリへのシンボリックリンクを上書きする際に役に立つことがある。例として、3つのディレクト2007,2008,2009があり、シンボリックリンクcurrentディレクト2008を指している状態だったとして

drwxr-xr-x 2 user group 40 2007-12-31 12:34 2007/
drwxr-xr-x 2 user group 40 2008-12-31 12:34 2008/
drwxr-xr-x 2 user group 40 2009-12-31 12:34 2009/
lrwxrwxrwx 1 user group  5 2008-12-31 23:45 current -> 2008/

このリンク先を2009に変更したい場合

$ ln -fns 2009 current 

としないと

drwxr-xr-x 2 user group 40 2007-12-31 12:34 2007/
drwxr-xr-x 2 user group 40 2008-12-31 12:34 2008/
drwxr-xr-x 2 user group 40 2009-12-31 12:34 2009/
lrwxrwxrwx 1 user group  5 2009-12-31 23:45 current -> 2009/

のようにはならない。もし

$ ln -fs 2008 current

とすると、この時点でcurrentが指し示す2008ディレクトリの中に無意味なシンボリックリンクを作成してしまう。

シンボリックリンクとパスの種類

ファイルやディレクトリの場所を示すパスには

の2種類があり、シンボリックリンクについても、両方の種類で作成できる。

$ ln -s /path/to/foo
もしくは
$ ln -s /path/to/foo .

のように対象を絶対パス表記すると、作成されたリンクは常にその絶対パス「/path/to/foo」を参照し

$ ln -s ../file
もしくは
$ ln -s ../file .

のように相対パス表記すると、そのシンボリックリンクがその後どこか別のディレクトリに移動されたとしても、このときにそのリンクのあるディレクトリを基準に1つ上の階層の「file」を参照する。
(2015/1/14)manページのリンク先を修正

まとめドキュメント:

関連URL:

*1:例えば「/path/to/foo」と「/path/to/bar」

*2:「link」より

*3:マウントされているディスク/パーティションが異なるハードリンクは作れず「無効なクロスデバイスリンクです」となる

*4:元々の参照(親から) x 1 + 「.」のハードリンク(自分から) x 1 + 「..」のハードリンク(それぞれの子から) x [子ディレクトリ数]

*5:最上位の階層からたどった形式で「/ 地球 / アジア / 日本 / AAA県 / BBB市 / CCC町 / N番地 ... 」のような感覚の表記

*6:「このCCC町を出てBBB市を出て(AAA県内を移動して)DDD市に入ってEEE町に入ってM番地...」のように、その階層からどのようにたどるかを記した形式