1. ホーム
  2. コース一覧
  3. Linux基礎コース(パート2)
  4. シンボリックリンク

Linux基礎コース(パート2)8/9

シンボリックリンク

ここではシンボリックリンクについて学習します。

シンボリックリンクとは、ある特定のファイルやディレクトリのパスを保存し、使用することで実際にそのパスにアクセスできるもののことです。

また、lnコマンドやunlinkコマンドを使うことで、シンボリックリンクを編集することが出来ます。

シンボリックリンクとは?

特定のファイルあるいはディレクトリへのリンク先を格納した別のファイルのことです。

シンボリックリンクにアクセスすると、格納されたリンク先へ飛ぶことができます。

UNIX系OSでは一般的に、lnコマンドでシンボリックリンクが作成でき、ファイルシステム上には本体の場所が記録された0バイトのファイルが出現します。

シンボリックリンクを指定して操作を行った場合は、自動的に本体の方に操作が反映されます。

一方でシンボリックリンクを削除しても、本体には影響はありません。

また、別のファイルシステムや装置にあっても参照できたり、特定のファイルやディレクトリが存在しない場合や、存在するかどうかわからない場合であってもシンボリックリンクは作成できます。

なお、本体の元の場所が移動されたり、ファイル名やディレクトリ名が変更になった場合は参照できなくなります。

シンボリックリンクの似た機能に「ハードリンク」というものもあります。

ハードリンクは、特定のファイルやディレクトリに対して、複数の名称(パス)が設定できます。

シンボリックリンクの様にリンクファイルからアクセスするのではなく、直接ファイルに対して操作ができるので、削除をおこなったり、場所や名称が変わっても参照することができますが、必ずファイルシステム内に存在するファイルでないと設定できません。

なぜ必要なのか?

上記説明の下線部にもありますが、主に別のファイルや装置でも参照できることが実際の現場では大いに役立つからです。

例えば、あるプロジェクトの開発をするのに仮想環境を構築したとします。

テスト的にコードをローカルで書きたい時などが発生した場合に、基本的に直接仮想環境のファイルやディレクトリにアクセスすることができません。

なぜなら、仮想環境とホスト環境は全くの別物として扱われるからです。

そこで、その課題を解決してくれるのがシンボリックリンクとなります。

ただし、単純にシンボリックリンクを作っただけでは解決はできなくて、以下が必要になります。

  • 特定のファイルまたはディレクトリのパス
  • リンク先の本体のアクセス権限付与

当然外部の環境にアクセスするので、アクセスしたい場所を指定するのとアクセスができる状態にしておくことが前提となります。

lnコマンド

シンボリックリンクの作成及び変更を行うコマンドです。

作成には -sオプションを使います

基本構文は以下です。

ln -s リンク元 登録名

testディレクトリの中にtest.txtがあったとします。

ls
test.txt

homeディレクトリにて、testFileという名前でシンボリックリンクを作成します。

作成する際は、-sオプションを使います。

ln -s test/test.txt testFile

ls -lでシンボリックリンクの確認をしてみましょう。

ls -l testFile
lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt

testFileが、test/test.txtを参照していることがわかります。

また、ファイル属性がlrwxrwxrwxとなっており、先頭のlがシンボリックリンクを表しています。

シンボリックリンクはショートカットの様なものなので、当然中身も見ることができます。

test.txtの中身が以下の様になっているとします。

# test.txt
testtest01

homeディレクトリで先ほど作ったシンボリックリンクのファイル名を使ってcatコマンドで中身を表示させてみましょう。

cat testFile
testtest01

この様に、別のディレクトリにあるファイルにアクセスできます。

注意点

シンボリックリンクの作成には、-sオプションを使うと説明しました。

では、オプションなしの場合はどうなるでしょうか。

オプションなしで操作した場合は、ハードリンクが作成されます。

ln test/test.txt test01
ls -l test01
-rw-r--r-- 2 envader envader 11  215 18:38 test01

ファイル属性の先頭に何も表示されていないですね。

シンボリックリンクを作成したつもりが、ハードリンクになっていたという可能性もありますので、注意してください。

主なオプション

オプション説明
-sシンボリックリンクの作成
-f既存のシンボリックリンクの内容を上書きする
-nリンクの指定先がディレクトリの場合、参照先に作成せずシンボリックリンクそのものを置き換える
-i上書きする際に、確認メッセージが表示される
-vリンクを登録する際に、登録する名前とリンク先を表示する
-b既存のシンボリックリンクの元リンクをバックアップし、新規に登録をする
--backup[=CONTROL]既存のシンボリックリンクの元リンクをCONTROLで指定された方法でバックアップし、新規に登録する
-S[SUFFIX]バックアップした元の登録名の後ろにSUFFIXで指定した文字を設定する

-f オプション

既存のシンボリックリンクと同じ名前で新規に登録しようとするとエラーが発生します。

同じ名前を使って違うリンク先を登録したい場合は -f オプションを使うことで、登録内容を上書きすることができます。

例) testFile というシンボリックリンクの内容をTESTディレクトリのTEST.txt上書きする

ls -l testFile
lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt

# -f オプションなし
ln -s TEST/TEST.txt testFile
ln: failed to create symbolic link 'testFile': File exists # エラーとなる

# -f オプションあり
ln -fs TEST/TEST.txt testFile
ls -l testfile
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt # 上書きされた

-n オプション

シンボリックリンクまたはハードリンク作成の時に参照先がディレクトリだった場合、シンボリックリンクそのものを置き換える(-fオプションと組み合わせて使用する)

-nオプションをつけなかった場合、参照先が変更されません。

ls -l testFile
lrwxrwxrwx 1 envader envader 5  215 18:19 testFile -> test/ # 参照先がディレクトリ

ln -fs TEST/TEST.txt testFile # 上書き
 ls -l testFile 
lrwxrwxrwx 1 envader envader 5  215 18:19 testFile -> test/ # 上書きできていない

参照先がディレクトリになっているシンボリックリンクを別の参照先に変更したい場合は、オプションを**-nfs**とします。

ln -nfs TEST/TEST.txt testFile
ls -l testFile
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt # 上書きされた

-i オプション

-fオプションでは強制的に上書きがされてしまいますが、上書きするかどうかの確認を入れたいときは**-i**オプションを使います。

ls -l testFile
lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt

ln -i -s TEST/TEST.txt testFile
ln: replace 'testFile'? y # 確認メッセージが表示され、yで上書きを許可する
ls -l testfile
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt 

-v オプション

登録したリンクが、正しくできているかを確認する場合につけるオプションです。

ファイル名とリンク先を表示してくれます。

ln -vs test/test.txt testFile
'testFile' -> 'test/test.txt' # リンクを作成時にファイル名とリンク先が表示される

-b オプション

既存のシンボリックリンクの同じ名前で別リンクを登録する場合に、上書きをせずにバックアップファイルを作って、新規に登録するオプションです。

例) 既存のtestFileというシンボリックリンクのバックアップファイルを作って、同じ名前で新たにTEST/TEST.txtへのシンボリックリンクを作成する

ls -l testFile
lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt

ln -bs TEST/TEST.txt testFile
ls -l testFile*
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
lrwxrwxrwx 1 envader envader 13  219 18:19 testFile~ -> test/test.txt 

バックアップファイルの名前には~(チルダ)が名前の最後につきます。

なので、検索やファイル表示などする際はファイル名の後に*(アスタリスク)をつけると表示されます。

-backup[=CONTROL] オプション

このオプションでは、CONTROLにパラメーターを設定して、バックアップファイルの細かい設定を行う時に使います。

パラメーターの種類は以下になります。

  • noneまたはoff

    バックアップを明示的に作成しない時に設定/作成しないという設定をする時に使用します。

    ls -l testFile
    lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt
    
    ln --backup=none -s TEST/TEST.txt testFile
    ln: failed to create symbolic link 'testFile': File exists
    # 訳)シンボリックリンクの作成に失敗しました。ファイルが存在します

    この様に上書きと一緒の操作になり、既にtestFileのシンボリックリンクがあるため、エラーとなります。

  • numberedまたはt

    バックアップファイルを番号付きで作成する時に設定します。

    ls -l testFile
    lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt
    
    ln --backup=numbered -s TEST/TEST.txt testFile
    ls -l testFile*
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~1~ -> test/test.txt

    バックファイル名がtestFile.~1~になっている通り、ファイル名の後ろに~1~がつきます。

    なお、番号付きで作成したバックアップファイルは隠し属性がつくので、GUI操作のファイルマネージャーでリンクを見ようとすると初期設定では隠れる様になっています。

  • existingまたnil

    既にバックアップした登録名に番号付きのバックファイルがあった場合は、連番での番号付きバックファイルを作成する時に設定します。

    ls -l testFile
    lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt
    
    ln --backup=numbered -s TEST/TEST.txt testFile
    ls -l testFile*
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
    lrwxrwxrwx 1 envader envader 13  219 18:19 testFile.~1~ -> test/test.txt
    
    ln --backup=existing -s test/test2.txt testFile
    ls -l testFile*
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> test/test2.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~1~ -> test/test.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~2~ -> TEST/TEST.txt

    testFile.~2~のようにexistingを使うと連番での番号付きバックアップファイルが作成されます。

    番号付きのバックアップファイルがない場合は、バックアップファイル名の後ろに~が着くだけとなる。

    ls -l testFile
    lrwxrwxrwx 1 envader envader   13  215 18:19 testFile -> test/test.txt
    
    ln --backup=existing -s TEST/TEST.txt testFile
    ls -l testFile*
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile~ -> test/test.txt
    

    バックアップファイルのポリシーがある場合**--backup=[CONTROL]**オプションを使います。

    • バックアップファイルの履歴を全て残したい場合
      • 初めの上書きはnumberedまたはtパラメーターで行う
    • バックアップファイルの作成は直前の1回で良い場合
      • 初めの上書きはexistingパラメーターをつける

    初回の設定以降は、どちらもexistingオプションを付けるだけで良いです。

  • simpleまたはnever

    既に番号付きのバックアップファルが作成されている状態で、番号付きでない同名のバックアップファルを作成したい時に設定します。

    ls -l testFile*
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> test/test3.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~1~ -> test/test.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~2~ -> test/test2.txt
    
    ln --backup=simple -s TEST/TEST.txt testFile
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~1~ -> test/test.txt
    lrwxrwxrwx 1 envader envader 14  215 18:19 testFile.~2~ -> test/test2.txt
    lrwxrwxrwx 1 envader envader 14  215 18:19 testFile~ -> test/test3.txt

    simpleパラメーターを使った場合、~のみがファイル名の後ろにつきます。

    その後、existingパラメーターを使ってバックアップファイルを作成した場合は、連番の最後の番号から続けて番号が設定されます。

    ln --backup=existing -s test/test4.txt testFile
    ls -l testFile*
    lrwxrwxrwx 1 envader envader 14  215 18:19 testFile -> test/test4.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~1~ -> test/test.txt
    lrwxrwxrwx 1 envader envader 14  215 18:19 testFile.~2~ -> test/test2.txt
    lrwxrwxrwx 1 envader envader 13  215 18:19 testFile.~3~ -> TEST/TEST.txt
    lrwxrwxrwx 1 envader envader 14  215 18:19 testFile~ -> test/test3.txt

-S [SUFFIX] オプション

このオプションは任意の文字をバックアップファイルに付けることができます。

ln -s test/test.txt testFile
ln -S Envader -s TEST/TEST.txt testFile
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> TEST/TEST.txt
lrwxrwxrwx 1 envader envader 13  215 18:19 testFileEnvader -> test/test.txt

注意点として、ディレクトリとして意味がある*, /などの一部の記号文字は使えません。

その他にもオプションがありますので、ぜひ調べてみてください。

unlinkコマンド

このコマンドは、シンボリックリンクやハードリンクの削除に使うコマンドです。

ln -s test/test.txt testFile
ls -l testFile
lrwxrwxrwx 1 envader envader 13  2月 15 18:19 testFile -> test/test.txt

unlink testFile
ls -l testFile
ls: cannot access 'testFile': No such file or directory

注意点

リンクを削除する際に、シンボリックリンクではなく元リンクを指定して削除した場合、その元リンク先のファイルまたはディレクトリは削除されてしまいますので注意してください。

つまり、rmコマンドと同様の操作になります。

ln -s test/test.txt testFile
ls -l testFile
lrwxrwxrwx 1 envader envader 13  215 18:19 testFile -> test/test.txt

unlink test/test.txt # 元リンク
ln test/test.txt testFile # -sオプションをつけずに、ハードリンクを作成してみる
ln: failed to access 'test/test': No such file or directory
# 訳)シンボリックリンクの作成に失敗しました。ファイルまたはディレクトリが存在しません。

unlinkコマンドを使う際は必ず削除先がシンボリックリンクまたはハードリンクになっていることを確認しましょう。

まとめ

今回は、シンボリックリンクについてとlnコマンド、unlinkコマンドについて学びました。

うまく使いこなせればファイルやディレクトリへのアクセスが容易になりますし、複数のシステムを跨いでのアクセスも容易になりますので、いろいろと試してみながら使い方を覚えていってください。

問題を解くためには、十分な画面サイズのPC環境をご利用下さい。