コマンドラインの基本:シンボリックリンク
序章
シンボリックリンクを使用すると、ファイルやディレクトリを他のファイルやディレクトリにリンクできます。 それらは、シンボリックリンク、シェルリンク、ソフトリンク、ショートカット、エイリアスなど、多くの名前で呼ばれています。 ユーザーの観点からは、シンボリックリンクは通常のファイルやディレクトリと非常によく似ています。 ただし、それらと対話すると、実際にはもう一方の端のターゲットと対話します。 それらをファイルシステムのワームホールのように考えてください。
このガイドでは、シンボリックリンクとは何か、および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
コマンドに渡すことができます。
注:シンボリックリンクは通常、ハードリンクよりも頻繁に使用されるため、ln
をln -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
変更したシンボリックリンクは別のファイルへのポインタにすぎないため、リンクに加えた変更は、元のファイルと他のシンボリックリンクにすぐに反映されます。
結論
シンボリックリンクは非常に便利ですが、特定の制限があります。 元のファイルまたはディレクトリを移動または削除すると、それを指す既存のシンボリックリンクがすべて壊れてしまうことに注意してください。 そのシナリオでは自動更新はありません。 ただし、注意している限り、コマンドラインで作業を続けると、シンボリックリンクの多くの用途を見つけることができます。