我想删除一个符号链接并将其链接到不同的东西,我认为有 3 种方法可以做到这一点:
ln -sfn source dest
rm dest
ln -s source dest
unlink dest
ln -s source dest
这三个都等价吗?应该优先选择其中一个吗?
答案1
它们并不等同。
在:
ln -sfn source dest
不取消引用目标的选项-n
是一个非标准扩展(我相信来自 GNU ln
,在 1994 年的 3.10 版本中添加)。其他一些ln
s 具有-h
相同的功能(例如自 1997 年以来的 NetBSD),而在其他一些上,例如 Solaris/Illumos 则-n
具有其他功能(早于 GNU ln
)-n
。
假设 的 GNU 行为-n
,如果dest
作为目录存在,则创建一个dest/source
文件来替换同名的文件(如果有),只要它本身不是目录。
否则,如果有的话,将创建一个dest
符号链接来source
替换现有文件。
ln
喜欢cp
或mv
有那个令人讨厌的模糊界面,他们可以在其中进行移动/复制/链接到目的地或进入目的地,但这取决于最后一个参数的类型(或参数的数量),而不是用户想要的。
在:
rm dest
ln -s source dest
rm
将尝试删除 a dest
,在某些情况下可能会提示用户,并且无论是否rm
成功都会运行,ln -s source dest
这将创建dest/source
(如果是无法删除的dest
目录或指向可能无法删除的目录的符号链接)例如,因为您没有对当前目录的写访问权限),或者作为源的符号链接(如果非目录文件以该名称存在则失败)。rm
rm
dest
和:
unlink dest
ln -s source dest
除了提示部分之外,以及在某些系统和某些条件下,unlink
可能能够取消目录链接这一事实,其他都是相同的。unlink
也在 POSIX 规范中的 XSI 选项下进行标记,并且不会像rm
.
因此,如果目的是尝试创建 的dest
符号链接source
,您宁愿:
GNU 特定:
ln -sfT source dest
(其中
-T
禁用进入模式,将其dest
视为要创建的预期文件,无论它是否是目录)。便携的:
rm -f dest && ln -sf source dest
rm
with-f
不会提示用户,并且如果文件一开始不存在也不会失败。当它成功时,您知道该文件不再存在(或者至少rm
在成功删除它后当时没有检查过)。但请注意,如果其他人(重新)创建了目录或到和之间的目录的符号链接,ln
仍然可能会创建符号链接。source/dest
dest
rm
ln
答案2
ln -sfn source dest
至少 GNU coreutils 的文档ln
具有误导性。它说:
-f, --force
删除现有的目标文件
实际上,GNUln -f
所做的是在临时名称下创建一个新的符号链接,然后调用renameat
,这只是原子地替换目标符号链接。确实如此不是首先删除现有的符号链接。
总的来说,这是可取的,所以不确定为什么man ln
撒谎。
在这种情况下,只需结果
那么事情就没有什么不同了。