現在のディレクトリを変更せずにサブディレクトリ内のシンボリックエイリアスファイル


11

サブディレクトリを移動せずに、1つのファイルをサブディレクトリ内の新しいファイルにシンボリックリンクするのは簡単なようです。しかし、構文についての何かは当惑し、私が期待するものに反しています。ここにテストケースがあります:

mkdir temp
cd temp
mkdir deploy
echo "Contents of the build file!" > deploy/resources.build.php
ln -s deploy/resources.build.php deploy/resources.php
cat deploy/resources.php #bad symlink

これは壊れたシンボリックリンクを作成するだけです!ビルド環境のセットアップスクリプトでこれを実行しているので、可能な限り、現在の作業ディレクトリを変更しないようにします。

ln -s deploy/resources.build.php resources.php
cat deploy/resources.php

また、デプロイサブディレクトリではなく一時ディレクトリにシンボリックリンクを作成するため、機能しません。

cd deploy
ln -s resources.build.php resources.php
cd ..

これは機能しますが、ディレクトリを変更せずに実行する方法を知りたいと思います。

次のような完全パスを使用します。

/home/whatever/src/project/temp/stuff/temp/deploy/resources.build.php

機能しますが、特にプロジェクト環境がビルド間で異なる可能性があるビルド環境などでは、不可解でやや実用的ではありません。

サブディレクトリに移動したりサブディレクトリから移動したりせずに、サブディレクトリ内の2つのファイル間にシンボリックリンクを作成し、新しいファイルに「エイリアス」に新しい名前を付けるにはどうすればよいですか。

回答:


10

しかし、構文についての何かは当惑し、私が期待するものに反しています。

の引数はln、使用している形式では次のとおりです。

ln [OPTION] ... [-T] TARGET LINK_NAME(1番目のフォーム)

複雑で直感的でないのは、シンボリックリンクを作成するときのターゲット引数lnはファイルへのパスではなく、作成されるシンボリックリンクの内容であると想定されていることです。少し考えてみれば、そのようにする必要があることは明らかです。検討してください:

$ echo foo >foo
$ ln -s foo bar1
$ ln -s $PWD/foo bar2
$ cat bar1
foo
$ cat bar2
foo
$ ls -l bar1 bar2
lrwxrwxrwx 1 matt matt  3 Dec 29 16:29 bar1 -> foo
lrwxrwxrwx 1 matt matt 29 Dec 29 16:29 bar2 -> /home/matt/testdir/foo

その例では、同じファイルを指す「bar1」と「bar2」という名前の2つのシンボリックリンクを作成します。 lsは、シンボリックリンク自体の内容が異なることを示しています。1つは絶対パスを含み、もう1つは相対パスを含みます。このため、一方が別のディレクトリに移動されても機能し続け、もう一方は機能しません。

$ mv bar2 /tmp
$ cat /tmp/bar2
foo
$ mv bar1 /tmp
$ cat /tmp/bar1
cat: /tmp/bar1: No such file or directory

したがって、相対シンボリックリンクと絶対シンボリックリンクの両方を作成できなければならず、後でターゲットファイルが作成されたときに壊れないシンボリックリンクを作成することもできることを考えると、ターゲット引数は、既存のファイルへのパス。

deploy / resources.build.phpにリンクするdeploy / resources.phpという名前のファイルを作成する場合は、絶対シンボリックリンクを作成するかどうかを決定する必要があります(これは、移動されるシンボリックリンクに対して耐性がありますが、ターゲットが移動された)、または相対シンボリックリンク(シンボリックリンクとターゲットの両方が一緒に移動され、同じ相対パスを維持している限り、機能し続けます)。

絶対シンボリックリンクを作成するには、次のようにします。

$ ln -s $PWD/deploy/resources.build.php deploy/resources.php

相対パスを作成するには、まずソースからターゲットへの相対パスを把握します。この場合、ソースとターゲットは互いに同じディレクトリにあるため、次のようにすることができます。

$ ln -s resources.build.php deploy/resources.php

同じディレクトリにない場合は、代わりに次のようにする必要があります。

$ ln -s ../foo/f bar/b

にもかかわらず、その場合、fooおよびbar現在のディレクトリの両方である、あなたは含める必要がある../ln ターゲットそれが検索する方法について説明しますので、f入っているディレクトリからb

これは非常に長い説明ですが、ln構文を少しよく理解するのに役立つことを願っています。


3

次のように、サブシェルでリンクを作成できます。

  (cd deploy && ln -s resources.build.php resources.php && cat resources.php)

サブシェルが実行を終了しても、まだ正しいディレクトリにいることがわかります。

別の方法として、

 ln -s resources.build.php deploy/resources.php

これも機能し、CLにresources.build.phpファイルがコマンドを発行しているディレクトリではなく、実際には./deploy内にあるという事実を含めることを無視しています。


これは黒魔術です、先生!
Kzqai

1

これは、シンボリックリンクが基本的に設定ファイルであることに気づくまで混乱しました。つまり、そのパスデータを単純なテキストファイルにどのように書き込むでしょうか。

ln -s [target] [link name]

になる:

echo [target] > [link name]

私(そしておそらくOP)が犯していたエラーは、lnが対象とするファイルについて知る必要があると考えていることです。lnは関係ありません。パス情報をファイルに書き込むだけです。これは完全に妥当なlnコマンドです。

ln -s /path/doesnt/exist/file.err
ll
file.err -> /path/doesnt/exist/file.err

したがって:

ln -s deploy/resources.build.php deploy/resources.php

フォルダー内のファイルを参照resources.phpしている./deployフォルダーで呼び出されるsimlinkファイルを生成resources.build.phpします./deploy/deploy/

それはあなたが望むものではなく、悪い(壊れた)リンクを与えます。リンクに問題はありません。そのファイルをそこに配置すると、リンクは機能します。しかし、(他の人が指摘したように)私とOPが望んだのは:

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