シンボリックリンクのターゲットは、宛先の親ディレクトリに相対的ですか?もしそうであれば、なぜですか?


14

私は次のファイル構造を持っています:

build/
client/
  –> index.js

そして、cwdのクライアントディレクトリを参照するビルドディレクトリ内に「client」というシンボリックリンクを作成しようとすると

// Fails
$ pwd
/home/user/
$ ln -s client build/client 
$ stat build/client/index.js
stat: build/client/index.js: stat: Too many levels of symbolic links

上記のELOOPエラーが表示されます。ターゲットパスを宛先パスに相対するように変更すると、すべてが正常になります。

// Works
$ pwd
/home/user/
$ ln -s ../client build/client 
$ stat build/client/index.js
stat: <outputs file stats>

これは意図した動作ですか?その理由を説明してください...


これはおそらく、.. /を使用して相対パスの代わりに絶対パスを使用するという事実と関係があります。良いpraticeは常に絶対パスを使用することです
Kiwy

ターゲットと宛先の両方に常に絶対パスを使用してきたため、ベストプラクティスに同意します。しかし、相対パスは両方に使用することができ、manページの状態...
jibsales

回答:


13

動作しないものについては、ls -l結果を見ると、次のものが得られます:

[sparticvs@sparta test]$ ls -l build/
total 0
lrwxrwxrwx. 1 sparticvs sparticvs 6 Dec 17 16:08 client -> client

ここで何が起こっているかを理解するために。呼び出したコマンドを見てみましょう。

ln -s client build/client

マニュアルページによると、この形式には2つの一致が考えられます

SYNOPSIS
       ln [OPTION]... [-T] TARGET LINK_NAME   (1st form)
       ln [OPTION]... TARGET... DIRECTORY     (3rd form)

最初のフォームで一致します(最初のフォームから)。これで、「ターゲット名」またはclient場合によっては、(完全なlnマニュアルによれば)任意の文字列にすることができます。今すぐ解決する必要はありませんが、将来は解決できます。呼び出しで作成しているのは「ダングリングシンボリックリンク」であり、システムはこれらの作成を妨げません。

これで、2番目の呼び出しln -s ../client build/clientは「相対シンボリックリンク」と呼ばれるものになります(自分の投稿で述べたように)。2番目のタイプがあり、これはを実行することで呼び出される「絶対シンボリックリンク」ln -s /home/user/client build/clientです。

これはバグではありません。マニュアルによると:

現在のディレクトリとは異なる場所に相対シンボリックリンクを作成する場合、シンボリックリンクの解像度は、現在のディレクトリの同じ文字列の解像度とは異なります。したがって、多くのユーザーは、最初にディレクトリを相対シンボリックリンクが作成される場所に変更し、タブ補完または他のファイル解決がシンボリックリンクに配置されるものと同じターゲットを見つけることを好みます。

-から info coreutils 'ln invocation'

それはあなたが、言ったしなければならないターゲットの相対パスまたは絶対パスのいずれかを使用します。


5

これは実際に意図された動作です。ln(1)manページから:

シンボリックリンクは任意のテキストを保持できます。後で解決される場合、相対リンクはその親ディレクトリに関連して解釈されます。

その理由については、シンボリックリンクが宛先ではなくソースを基準にして解釈されたかどうかを想像してください。後で解決するときは、CWDを作成したときのCWDが何であるかを知る必要があります。これは無意味であり、不可能です。

さらに、このようにすれば、シンボリックリンクを壊すことなくディレクトリツリーのどこにでもドロップできるスケルトンディレクトリ構造を作成するためのきちんとしたコンパクトな方法を得ることができます。

私が言いたいことの例を挙げるために、あなたがプロジェクトに取り組んでいて、そのためにディレクトリ構造全体が設定されているとしましょう:

$ ls -1 /home/you/project
thingummies/
widgets/
wizardry/

ここで、widgets/inside へのシンボリックリンクを作成するとしますwizardry/。次の2つのオプションがあります。

$ ln -s /home/you/project/widgets /home/you/project/wizardry

または

$ ln -s ../widgets /home/you/project/wizardry

その後/home/you/project、他の場所に移動しようとすると、最初のフォームで作成されたシンボリックリンクはを探しているため壊れ/home/you/project/widgetsます。2番目の形式では、ディレクトリツリー内の場所に関係なく、その場所に../widgets 関連して検索するため、シンボリックリンクは機能し続けます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.