Symlink

GNU Stow 可以使用作為符號連結的儲存目錄嗎?

  • June 28, 2019

考慮這個腳本。

#! /usr/bin/env bash

mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file

ln --symbolic mydir mylink
file mylink

stow --verbose --dir=./mylink --target=./target package

file target/file

輸出是

mylink: symbolic link to mydir
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

在執行之前stow,它看起來像這樣:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target

執行stow, on後mylink,我希望它看起來像這樣:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
   └── file -> ../mylink/package/file

但是,它看起來像這樣:

.
├── mydir
│   └── package
│       └── file
├── mylink -> mydir
└── target
   └── file -> ../mydir/package/file

似乎該stow命令解析了包目錄的真實路徑,所以不是指向../mylink/package/file它,而是指向../mydir/package/file.

這對於避免過多的間接是有意義的,但它會默默地發生並且可能並不總是可取的。有沒有辦法解決這種行為?

**編輯:**根據請求,我將描述一個解析真實路徑不方便的範例案例。

符號連結有時用於兼容性。Debian 甚至在官方政策中談到了這一點。目標通常是單個文件,但有時是目錄 。我的系統上恰好有幾百個/usr/share/doc/

$ find /usr/share/doc -xtype d -type l | wc -l
325

stow只要符號連結目標不移動,預設行為就可以了。但有時所需的目標目錄確實會被移動。例如,在 Debian 上,vim-runtime軟體包將 /usr/share/vim/ 下的文件安裝在依賴於版本的目錄中,例如/usr/share/vim/vim64版本 6.4。但是,該軟體包還將更新 指向目前版本的符號連結。/usr/share/vim/vimcurrent這意味著一個符號連結指向,比如說

/usr/share/vim/vim64/doc/cmdline.txt

當 Debian 的下一個版本將其升級到

/usr/share/vim/vim70/doc/cmdline.txt

但是一個符號連結到

/usr/share/vim/vimcurrent/doc/cmdline.txt

可以在兩個版本中使用。

由於stow使用 stow 目錄的絕對規範路徑,因此呼叫如下

stow --dir=/usr/share/vim/vimcurrent --target=./my-vim-docs doc

會導致符號連結,例如:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vim64/doc/cmdline.txt

不是這樣的:

$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vimcurrent/doc/cmdline.txt

stow(使用on的動機vimcurrent/docs 是能夠將我自己的 vim 註釋與目前文件的符號連結混合在一起。)請注意,vimcurrent兼容性符號連結 不再存在於目前的 Debian 發行版中, 儘管它可能存在於 Arch Linux 等其他發行版中;我不知道。無論如何,這裡有一個腳本,它給出了 vim 文件的總體構想:

#! /usr/bin/env bash
mkdir -p target
ln --symbolic /usr/share/vim/vim80 vimcurrent
stow --verbose --dir=./vimcurrent --target=./target pack
file target/dist

輸出是:

LINK: dist => ../../../../../usr/share/vim/vim80/pack/dist
target/dist: symbolic link to ../../../../../usr/share/vim/vim80/pack/dist

假設,stow可以有一個名為的標誌,比如說,,--no-realpath所以輸出看起來像這樣:

LINK: dist => ./vimcurrent/pack/dist
target/dist: symbolic link to ./vimcurrent/pack/dist

對於隨每個版本更改的兼容性符號連結的其他範例,以下是我在筆記型電腦上知道的另外兩個範例:

$ file /usr/share/go
/usr/share/go: symbolic link to go-1.10
$ file /usr/share/mscore
/usr/share/mscore: symbolic link to mscore-2.1

要解決符號連結點到符號連結的情況:

#! /usr/bin/env bash
mkdir -p target
mkdir -p mydir/package/
touch mydir/package/file
ln --symbolic mydir mylink
ln --symbolic mylink mylink2
namei mylink2

產生:

f: mylink2
l mylink2 -> mylink
  l mylink -> mydir
    d mydir

進而:

$ stow --verbose --dir=./mylink2 --target=./target package
$ file target/file

產生:

LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file

然而

$ stow --no-realpath --verbose --dir=./mylink2 --target=./target package
$ file target/file

會產生這個:

LINK: file => ../mylink2/package/file
target/file: symbolic link to ../mylink2/package/file

因此,在假設的--no-realpath行為中,它將 stow 目錄視為正常目錄。

此功能將適用於以下場景

  1. stow 目錄必須是符號連結,並且

2)希望在生成的符號連結中保留該連結。

雖然我不認為缺少這個特性是一個很大的缺陷stow,但我希望這個例子能夠闡明並不總是解決規範路徑的潛在有用性。

目前,沒有辦法。

在內部,通過使用chdir移動到stow路徑中找到給定路徑的絕對規範路徑,然後使用 POSIX 模組中的getcwd()函式,這是POSIX getcwd()的 Perl 介面,以獲取絕對路徑名。

正如 POSIX 所指定的,路徑名不應包含...、或符號連結的組件。

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