コマンドラインの基本:シンボリックリンク

提供:Dev Guides
移動先:案内検索

序章

シンボリックリンクを使用すると、ファイルやディレクトリを他のファイルやディレクトリにリンクできます。 それらは、シンボリックリンク、シェルリンク、ソフトリンク、ショートカット、エイリアスなど、多くの名前で呼ばれています。 ユーザーの観点からは、シンボリックリンクは通常のファイルやディレクトリと非常によく似ています。 ただし、それらと対話すると、実際にはもう一方の端のターゲットと対話します。 それらをファイルシステムのワームホールのように考えてください。

このガイドでは、シンボリックリンクとは何か、およびlnコマンドを使用してLinuxコマンドラインからシンボリックリンクを作成する方法の概要を説明します。

前提条件

このガイドに従うには、Linuxベースのオペレーティングシステムを実行しているコンピューターにアクセスする必要があります。 これは、SSHで接続した仮想プライベートサーバーまたはローカルマシンのいずれかです。 このチュートリアルは、Ubuntu 20.04を実行しているLinuxサーバーを使用して検証されていますが、示されている例は、任意のバージョンのLinuxディストリビューションを実行しているコンピューターで機能するはずです。

このガイドに従うためにリモートサーバーを使用する場合は、最初に初期サーバーセットアップガイドを完了することをお勧めします。 そうすることで、sudo権限を持つroot 以外のユーザーや、UFWで構成されたファイアウォールなどの安全なサーバー環境がセットアップされます。これを使用してLinuxスキルを構築できます。

または、このページに埋め込まれているインタラクティブ端末を使用して、このチュートリアルのサンプルコマンドを試すこともできます。 次のインタラクティブターミナルの起動!ボタンをクリックしてターミナルウィンドウを開き、Linux(Ubuntu)環境での作業を開始します。

インタラクティブターミナルを起動します!

ディレクトリとファイルの例の設定

シンボリックリンクを作成するために必要なシステムコールは、UnixライクなPOSIX準拠のオペレーティングシステムですぐに利用できる傾向があります。 リンクの作成に使用するコマンドは、lnコマンドです。

システム上の既存のファイルを使用してシンボリックリンクの作成を練習することはできますが、このセクションでは、このガイドの例に沿って実行できる練習環境を設定するいくつかのコマンドを提供します。

/tmp/ディレクトリ内にいくつかのディレクトリを作成することから始めます。 /tmp/一時ディレクトリです。つまり、サーバーが次に起動したときに、その中のすべてのファイルとディレクトリが削除されます。 これは、後でシステムを詰まらせることを心配することなく、必要な数のディレクトリ、ファイル、およびリンクを作成できるため、このガイドの目的に役立ちます。

次のmkdirコマンドは、一度に3つのディレクトリを作成します。 /tmp/ディレクトリ内にsymlinks/という名前のディレクトリを作成し、symlinks/内に2つのディレクトリ(one/という名前とtwo/という名前)を作成します。 :

mkdir -p /tmp/symlinks/{one,two}

新しいsymlinks/ディレクトリに移動します。

cd /tmp/symlinks

そこから、symlinks/内の両方のサブディレクトリ用に1つずつサンプルファイルをいくつか作成します。 次のコマンドは、one/サブディレクトリ内にone.txtという名前のファイルを作成します。このファイルの内容は、oneを読み取る1行だけです。

echo "one" > ./one/one.txt

同様に、このコマンドは、two/サブディレクトリ内にtwo.txtという名前のファイルを作成します。このファイルの内容は、twoを読み取る1行だけです。

echo "two" > ./two/two.txt

この時点でtreeを実行して、/tmp/symlinksディレクトリ全体とネストされたサブディレクトリの内容を表示すると、その出力は次のようになります。

tree
Output.
├── one
│   └── one.txt
└── two
    └── two.txt

2 directories, 2 files

treeがデフォルトでマシンにインストールされていない場合は、システムのパッケージマネージャーを使用してインストールできます。 たとえば、Ubuntuでは、aptを使用してインストールできます。

sudo apt install tree

これらのサンプルドキュメントを用意したら、シンボリックリンクの作成を練習する準備が整います。

ハードリンクを理解する

デフォルトでは、lnコマンドは、シンボリックリンクまたはソフトリンクの代わりにハードリンクを作成します。

テキストファイルがあるとします。 そのファイルへのシンボリックリンクを作成すると、そのリンクは元のファイルへのポインタにすぎません。 元のファイルを削除すると、ポイントするものがなくなったため、リンクが壊れます。

代わりに、ハードリンクはまったく同じ内容の元のファイルのミラーコピーです。 シンボリックリンクと同様に、元のファイルの内容を編集すると、それらの変更はハードリンクに反映されます。 ただし、元のファイルを削除しても、ハードリンクは引き続き機能し、元のファイルの通常のコピーと同じように表示および編集できます。

ハードリンクは世界でその目的を果たしますが、場合によっては完全に回避する必要があります。 たとえば、gitリポジトリ内でリンクする場合は、混乱を招く可能性があるため、ハードリンクの使用は避けてください。

シンボリックリンクを作成していることを確認するには、-sまたは--symbolicオプションをlnコマンドに渡すことができます。

:シンボリックリンクは通常、ハードリンクよりも頻繁に使用されるため、lnln -sにエイリアスすると便利な場合があります。

alias ln="ln -s"

これにより、数回のキーストロークしか節約できない場合がありますが、シンボリックリンクを多数作成している場合は、これが大幅に増える可能性があります。


シンボリックリンクの操作

前述のように、シンボリックリンクは、基本的に、ターゲットのファイル名とパスを含むファイルを作成するようなものです。 シンボリックリンクは元のファイルへの単なる参照であるため、元のファイルに加えられた変更は、シンボリックリンクですぐに利用できます。

シンボリックリンクの潜在的な用途の1つは、ユーザーのホームディレクトリに、Dropboxなどの外部アプリケーションに同期されているファイルを指すローカルディレクトリを作成することです。 もう1つは、動的に名前が付けられたディレクトリにあるプロジェクトの最新のビルドを指すシンボリックリンクを作成することです。

最初のセクションのサンプルファイルとディレクトリを使用して、先に進み、前に作成したoneディレクトリを指すthreeという名前のシンボリックリンクを作成してみてください。

ln -s one three

これで、3つのディレクトリが作成され、そのうちの1つが別のディレクトリを指しています。 現在のディレクトリ構造のより詳細な概要を取得するには、lsコマンドを使用して、現在の作業ディレクトリの内容を出力できます。

ls
Outputone  three  two

symlinks/ディレクトリ内に3つのディレクトリがあります。 システムによっては、threeが実際にはシンボリックリンクであることを示している場合があります。 これは、リンクの名前を別の色でレンダリングしたり、@記号を追加したりすることで実行される場合があります。

さらに詳細については、-l引数をlsに渡して、シンボリックリンクが実際に指している場所を特定できます。

ls -l
Outputtotal 8
drwxrwxr-x 2 sammy sammy 4096 Oct 30 19:51 one
lrwxrwxrwx 1 sammy sammy    3 Oct 30 19:55 three -> one
drwxrwxr-x 2 sammy sammy 4096 Oct 30 19:51 two

threeリンクが期待どおりにoneディレクトリを指していることに注意してください。 また、lで始まり、リンクであることを示します。 他の2つはdで始まります。これは、通常のディレクトリであることを意味します。

シンボリックリンクには、シンボリックリンクを含めることもできます。 例として、one.txtファイルをthreeからtwoディレクトリにリンクします。

ln -s three/one.txt two/one.txt

これで、twoディレクトリ内にone.txtという名前のファイルが作成されます。 次のlsコマンドで確認できます。

ls -l two/
Outputtotal 4
lrwxrwxrwx 1 sammy sammy 13 Oct 30 19:58 one.txt -> three/one.txt
-rw-rw-r-- 1 sammy sammy  4 Oct 30 19:51 two.txt

端末の構成によっては、リンク(この出力例で強調表示されている)が赤いテキストで表示され、リンク切れを示している場合があります。 リンクは作成されましたが、この例でパスを指定する方法は相対的なものでした。 twoディレクトリにone.txtファイルを含むthreeディレクトリが含まれていないため、リンクが壊れています。

幸い、lnに、-rまたは--relative引数を使用して、リンク位置を基準にしたシンボリックリンクを作成するように指示することで、この状況を改善できます。

ただし、-rフラグを使用しても、壊れたシンボリックリンクを修正することはできません。 この理由は、シンボリックリンクがすでに存在し、-fまたは--force引数を含めずに上書きすることはできないためです。

ln -srf three/one.txt two/one.txt

これで、one/one.txtへのリンクであるthree/one.txtにリンクされたtwo/one.txtができました。

このようなシンボリックリンクをネストするとすぐに混乱する可能性がありますが、多くのアプリケーションには、このようなリンク構造をより理解しやすくするための機能が備わっています。 たとえば、treeコマンドを実行した場合、表示されるリンクターゲットは実際には元のファイルの場所のターゲットであり、リンク自体ではありません。

tree
Output.
├── one
│   └── one.txt
├── three -> one
└── two
    ├── one.txt -> ../one/one.txt
    └── two.txt

3 directories, 3 files

物事がうまくリンクされたので、これらのサンプルファイルの内容を変更することにより、シンボリックリンクがファイルとどのように機能するかを探求し始めることができます。

ファイルの内容を理解するには、次のcatコマンドを実行して、このガイドで作成した3つのディレクトリのそれぞれにあるone.txtファイルの内容を出力します。

cat {one,two,three}/one.txt
Outputone
one
one

次に、one/ディレクトリから元のone.txtファイルの内容を更新します。

echo "1. One" > one/one.txt

次に、各ファイルの内容を再度確認します。

cat {one,two,three}/one.txt
Output1. One
1. One
1. One

この出力が示すように、元のファイルに加えた変更は、そのシンボリックリンクのいずれかに反映されます。

今、逆を試してみてください。 次のコマンドを実行して、シンボリックリンクの1つの内容を変更します。 この例では、three/ディレクトリ内のone.txtファイルの内容を変更します。

echo "One and done" > three/one.txt

次に、各ファイルの内容をもう一度確認します。

cat {one,two,three}/one.txt
OutputOne and done
One and done
One and done

変更したシンボリックリンクは別のファイルへのポインタにすぎないため、リンクに加えた変更は、元のファイルと他のシンボリックリンクにすぐに反映されます。

結論

シンボリックリンクは非常に便利ですが、特定の制限があります。 元のファイルまたはディレクトリを移動または削除すると、それを指す既存のシンボリックリンクがすべて壊れてしまうことに注意してください。 そのシナリオでは自動更新はありません。 ただし、注意している限り、コマンドラインで作業を続けると、シンボリックリンクの多くの用途を見つけることができます。