![例子](https://linux22.com/image/200889/%E4%BE%8B%E5%AD%90.png)
我想创建一个指向相对符号链接的相对符号链接,而不是指向相对符号链接的目标。似乎在创建相对符号链接时ln
解析TARGET
而不是指向实际的TARGET
.这个过程可以跳过吗?在下面的示例中,我想rsym-to-existing-rsym.txt
指向rsym-to-target.txt
,而不是指向target.txt
。
当我创建一个指向尚不存在的符号链接的符号链接时,它可以工作(下面示例中的rsym-to-future-rsym.txt
-> future-rsym-to-target.txt
->链)。target.txt
例子
# Create initial structure
$ mkdir -p temp
$ touch temp/target.txt
# Now, create relative symlinks
$ ln -s -r temp/target.txt temp/rsym-to-target.txt
$ ln -s -r temp/rsym-to-target.txt temp/rsym-to-existing-rsym.txt
# Note that at this point temp/future-rsym-to-target.txt doesn't exist yet
$ ln -s -r temp/future-rsym-to-target.txt temp/rsym-to-future-rsym.txt
$ ln -s -r temp/target.txt temp/future-rsym-to-target.txt
$ tree -F temp/
# Note that rsym-to-existing-rsym.txt points to target.txt, not to rsym-to-target.txt
temp/
├── future-rsym-to-target.txt -> target.txt
├── rsym-to-existing-rsym.txt -> target.txt
├── rsym-to-future-rsym.txt -> future-rsym-to-target.txt
├── rsym-to-target.txt -> target.txt
└── target.txt
# Maybe the tools I'm using are just nice to me and resolve final paths?
# No, when I delete rsym-to-target.txt symlink rsym-to-existing-rsym.txt still points to target.txt
$ rm temp/rsym-to-target.txt
tree -F temp/
temp/
├── future-rsym-to-target.txt -> target.txt
├── rsym-to-existing-rsym.txt -> target.txt
├── rsym-to-future-rsym.txt -> future-rsym-to-target.txt
└── target.txt
答案1
plainln -s
将其目标视为字符串。它不关心该字符串是否恰好是现有文件的路径。
GNU 扩展ln -sr
将其目标视为文件系统位置。它需要取消引用目标中的目录,因为否则生成的实际目标将是错误的:
mkdir /tmp/demo /tmp/foreign
cd /tmp/demo
mkdir child
ln -s -r foo child/foo # -> ../foo
ln -s /tmp/foreign elsewhere
ln -s -r foo elsewhere/foo # -> ../demo/foo — not ../foo
这本来可以在不取消引用路径的最终组件的情况下实现,但事实并非如此。
这手动的解释如何获取相对于给定目录的链接。不要使用ln -r
,而是调用realpath
(这也是 GNU coreutils 的一部分)来构建相对路径。根据您传递的是链接名称还是将在其中创建链接的目录名称,调用会有所不同。
如果$dir
是目录:
ln -s -- "$(realpath -m --relative-to "$dir" -- "$target")" "$dir"
If$linkname
是要创建的链接的路径:
ln -s -- "$(realpath -m --relative-to "$(dirname -- "$linkname")" -- "$target")" "$linkname"