Directory

子目錄中的符號連結別名文件而不更改目前目錄

  • September 1, 2020

將一個文件符號連結到子目錄中的新文件似乎應該很簡單…………而不移動子目錄。但是關於語法的一些東西令人困惑並且與我的預期相反。這是一個測試案例:

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

也不起作用,因為它在 temp 目錄而不是 deploy 子目錄中創建符號連結。

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

這行得通,但我更願意知道如何在不更改目錄的情況下做到這一點。

使用完整路徑,例如:

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

有效,但笨重且有些不切實際,尤其是在建構環境中,所有項目內容可能在建構之間有所不同,等等。

如何在子目錄中的兩個文件之間創建符號連結,而無需移入該子目錄並移出該子目錄,同時為新文件“別名”賦予新名稱?

但是關於語法的一些東西令人困惑並且與我的預期相反。

的參數ln,以您使用的形式,是:

ln

$$ OPTION $$…$$ -T $$TARGET LINK_NAME(第一種形式)

令人困惑、不直覺的是,當您創建符號連結時,目標參數 forln不應該是文件的路徑,而是要創建的符號連結的內容。如果你想一想,很明顯它必須是那樣的。考慮:

$ 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

在該範例中,我創建了 2 個符號連結,名為“bar1”和“bar2”,它們指向同一個文件。 ls顯示符號連結本身俱有不同的內容,但是 - 一個包含絕對路徑,一個包含相對路徑。因此,即使將其移至另一個目錄,一個仍會繼續工作,而另一個則不會:

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

因此,考慮到我們必須能夠創建相對符號連結和絕對符號連結,甚至創建損壞的符號連結,如果稍後創建目標文件,這些符號連結將不會損壞,因此必須將目標參數解釋為自由格式的文本,而不是已存在文件的路徑。

如果您想創建一個名為 deploy/resources.php 的文件,該文件連結到 deploy/resources.build.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

在這種情況下,即使foobar都在您的目前目錄中,您也需要將 a 包含../ln 目標中,因為它描述瞭如何f從包含b.

這是一個非常長的解釋,但希望它可以幫助您ln更好地理解語法。

引用自:https://unix.stackexchange.com/questions/176475