如何编辑符号链接?

Oli*_*Oli 80 filesystems symlink

我对符号链接的基本理解是作为一个特殊文件,一个包含另一个文件的字符串路径的文件。内核的 VFS 抽象了很多,但有什么理由说明符号链接似乎无法编辑吗?

换句话说:我可以编辑符号链接吗?如果没有,为什么不呢?


我确实理解有多种替换符号链接的方法(答案部分目前有两种替代方法),但是解释为什么替换似乎是处理符号链接的唯一方法会很有趣。为什么你不能改变他们指向的地方?

Oli*_*Oli 43

鉴于-f只是进行无声替换,您可以使用mv -T(-T 使其工作,即使 /loc.../link 是目录)进行原子替换

ln -s /location/to/link linkname
# ... 
ln -s /location/to/link2 newlink
mv -T newlink linkname
Run Code Online (Sandbox Code Playgroud)

linkname 在整个过程中都可以访问。

  • 这确实为您提供了原子替换,尽管您仍在进行替换而不是编辑(新链接具有新的 inode 编号)。 (9认同)
  • 这假设 `linkname` 不是目录的符号链接。如果在 GNU 上使用 `-T` 选项给 `mv`,如果在 FreeBSD 上使用 `-h` 来避免这种情况。请注意,像 `ln -sf` 这样不保留链接的权限(在它们很重要的系统上)。 (4认同)
  • @psusi 我完全同意,在某些情况下,它只是技术上比其他答案稍好一点的选择。 (2认同)

Nli*_*tis 26

如果通过编辑,您的意思是更改它指向的文件,那么是的,您可以:

$ ln -s .bashrc test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 7 2009-09-23 17:12 test -> .bashrc
$ ln -s .profile test
ln: creating symbolic link `test': File exists
$ ln -s -f .profile test
$ ls -al test
lrwxrwxrwx 1 pascal pascal 8 2009-09-23 17:12 test -> .profile
Run Code Online (Sandbox Code Playgroud)

传递给 ln的-f参数 ( --force) 会导致它unlink()在之前调用系统调用symlink()

取自以下堆栈溢出答案

  • 我认为这是否可以被视为“编辑”是有问题的,因为 unlink();symlink(); 不是原子的,因此在极短的时间内链接不存在。 (10认同)
  • 请注意,它假定 `test` 的目标不是目录。否则`ln -s -f .profile test` 将在该目录中创建一个`.profile` 符号链接。GNU `ln` 有一个 `-T` 选项来避免这种情况。 (6认同)
  • @mauro.stettler 是的,你是对的。但我想这取决于你的观点。如果你只考虑最终结果,那么也许你可以认为它是经过编辑的,不考虑其他事情。 (2认同)

Gil*_*il' 11

符号链接需要原子性地修改。如果你写到一半,它们就行不通了。符号链接的内容非常小(在 Linux 上最多 4095 个字符:文件路径的最大长度),因此在内核级别编辑符号链接的一部分几乎没有意义。因此,内核不提供任何编辑符号链接的接口,只有一个创建新符号链接的接口,即symlink系统调用(加上unlink删除任何文件的通用接口)。

symlink系统调用只能创建一个新的符号链接,它不会删除任何现有的文件。这很烦人,但与创建文件的其他系统调用一致,例如open(可以创建新文件或截断现有文件,但不能用新创建的文件替换现有文件)和mkdir.

在 shell 中,正如您所发现的,虽然您不能用ln命令原子地替换符号链接(ln -sf取消链接前一个文件,然后创建符号链接),但您可以先在临时名称下创建符号链接,然后然后将其移动到位。

tmp=$(TMPDIR=$(dirname -- "$link") mktemp)
ln -sf -- "$target" "$tmp"
mv -f "$tmp" "$link"
Run Code Online (Sandbox Code Playgroud)

  • 如果`$link`指向一个目录,`mv -f`(如`ln -sf`)将不会做你想做的事情。GNU ln 和 mv 有一个`-T`。`mv`(重命名系统调用)将_总是_改变 `$link` 的 inode,而 `ln -sfT`(unlink+symlink)可能会重用相同的 inode。 (2认同)