考虑这个脚本。
#! /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
Run Code Online (Sandbox Code Playgroud)
输出是
mylink: symbolic link to mydir
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file
Run Code Online (Sandbox Code Playgroud)
在运行之前stow
,它看起来像这样:
.
??? mydir
? ??? package
? ??? file
??? mylink -> mydir
??? target
Run Code Online (Sandbox Code Playgroud)
运行stow
, on 后mylink
,我希望它看起来像这样:
.
??? mydir
? ??? package
? ??? file
??? mylink -> mydir
??? target
??? file -> ../mylink/package/file
Run Code Online (Sandbox Code Playgroud)
但是,它看起来像这样:
.
??? mydir
? ??? package
? ??? file
??? mylink -> mydir
??? target
??? file -> ../mydir/package/file
Run Code Online (Sandbox Code Playgroud)
似乎该stow
命令解析了包目录的真实路径,所以不是指向../mylink/package/file
它而是指向../mydir/package/file
.
这对于避免过多的间接是有意义的,但它是默默发生的,可能并不总是可取的。有没有办法解决这种行为?
编辑:根据请求,我将描述一个示例用例,其中解析真实路径不方便。
符号链接有时用于兼容性。Debian 甚至在官方政策中谈到了这一点。通常目标是单个文件,但有时它是一个目录
。我的系统上碰巧有几百个/usr/share/doc/
:
$ find /usr/share/doc -xtype d -type l | wc -l
325
Run Code Online (Sandbox Code Playgroud)
stow
只要符号链接目标不移动,的默认行为就可以。但有时所需的目标目录确实会被移动。例如,在 Debian 上,该vim-runtime
软件包将 /usr/share/vim/ 下的文件安装在依赖于版本的目录中,例如/usr/share/vim/vim64
版本 6.4。但是,包也将更新一个符号链接
在/usr/share/vim/vimcurrent
该尖到最新版本。这意味着一个符号链接指向,说
/usr/share/vim/vim64/doc/cmdline.txt
Run Code Online (Sandbox Code Playgroud)
当 Debian 的下一个版本将其升级到
/usr/share/vim/vim70/doc/cmdline.txt
Run Code Online (Sandbox Code Playgroud)
但一个符号链接
/usr/share/vim/vimcurrent/doc/cmdline.txt
Run Code Online (Sandbox Code Playgroud)
将在两个版本中工作。
由于stow
使用 stow 目录的绝对规范路径,因此调用如下
stow --dir=/usr/share/vim/vimcurrent --target=./my-vim-docs doc
Run Code Online (Sandbox Code Playgroud)
会导致符号链接,例如:
$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vim64/doc/cmdline.txt
Run Code Online (Sandbox Code Playgroud)
不是这样的:
$ file cmdline.txt
cmdline.txt: symbolic link to ../../../../../usr/share/vim/vimcurrent/doc/cmdline.txt
Run Code Online (Sandbox Code Playgroud)
(使用stow
on的动机vimcurrent/docs
是能够将我自己的 vim 注释与指向当前文档的符号链接混合在一起。)请注意,当前 Debian 发行版中不再存在vimcurrent
兼容性符号链接
,
尽管它可能存在于其他发行版中,例如 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
Run Code Online (Sandbox Code Playgroud)
输出是:
LINK: dist => ../../../../../usr/share/vim/vim80/pack/dist
target/dist: symbolic link to ../../../../../usr/share/vim/vim80/pack/dist
Run Code Online (Sandbox Code Playgroud)
假设,stow
可以有一个名为,例如,的标志--no-realpath
,因此输出看起来像这样:
LINK: dist => ./vimcurrent/pack/dist
target/dist: symbolic link to ./vimcurrent/pack/dist
Run Code Online (Sandbox Code Playgroud)
对于随每个版本而变化的兼容性符号链接的其他示例,以下是我在笔记本电脑上知道的另外两个示例:
$ 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
Run Code Online (Sandbox Code Playgroud)
要解决符号链接点到符号链接的情况:
#! /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
Run Code Online (Sandbox Code Playgroud)
产生:
f: mylink2
l mylink2 -> mylink
l mylink -> mydir
d mydir
Run Code Online (Sandbox Code Playgroud)
进而:
$ stow --verbose --dir=./mylink2 --target=./target package
$ file target/file
Run Code Online (Sandbox Code Playgroud)
产生:
LINK: file => ../mydir/package/file
target/file: symbolic link to ../mydir/package/file
Run Code Online (Sandbox Code Playgroud)
然而
$ stow --no-realpath --verbose --dir=./mylink2 --target=./target package
$ file target/file
Run Code Online (Sandbox Code Playgroud)
会产生这个:
LINK: file => ../mylink2/package/file
target/file: symbolic link to ../mylink2/package/file
Run Code Online (Sandbox Code Playgroud)
因此,在假设--no-realpath
行为中,它会将 stow 目录视为常规目录。
此功能适用于以下场景
1) stow 目录必须是一个符号链接,并且
2)希望在生成的符号链接中保留该链接。
虽然我不认为缺少此功能是 的严重缺陷stow
,但我希望此示例阐明了不总是解析规范路径的潜在用途。
目前,没有办法。
在内部,stow
通过使用chdir移动到路径中找到给定路径的绝对规范路径,然后使用POSIX 模块中的getcwd()函数,它是POSIX getcwd()的 Perl 接口,以获得绝对路径名。
正如 POSIX 指定的那样,路径名不应包含是.
或..
或符号链接的组件。