ln -sfn 与 rm 与 unlink

ln -sfn 与 rm 与 unlink

我想删除一个符号链接并将其链接到不同的东西,我认为有 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 版本中添加)。其他一些lns 具有-h相同的功能(例如自 1997 年以来的 NetBSD),而在其他一些上,例如 Solaris/Illumos 则-n具有其他功能(早于 GNU ln-n

假设 的 GNU 行为-n,如果dest作为目录存在,则创建一个dest/source文件来替换同名的文件(如果有),只要它本身不是目录。

否则,如果有的话,将创建一个dest符号链接来source替换现有文件。

ln喜欢cpmv有那个令人讨厌的模糊界面,他们可以在其中进行移动/复制/链接目的地或进入目的地,但这取决于最后一个参数的类型(或参数的数量),而不是用户想要的。

在:

rm dest
ln -s source dest

rm将尝试删除 a dest,在某些情况下可能会提示用户,并且无论是否rm成功都会运行,ln -s source dest这将创建dest/source(如果是无法删除的dest目录或指向可能无法删除的目录的符号链接)例如,因为您没有对当前目录的写访问权限),或者作为源的符号链接(如果非目录文件以该名称存在则失败)。rmrmdest

和:

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
    

    rmwith-f不会提示用户,并且如果文件一开始不存在也不会失败。当它成功时,您知道该文件不再存在(或者至少rm在成功删除它后当时没有检查过)。但请注意,如果其他人(重新)创建了目录或到和之间的目录的符号链接,ln仍然可能会创建符号链接。source/destdestrmln

答案2

ln -sfn source dest

至少 GNU coreutils 的文档ln具有误导性。它说:

-f, --force
                     删除现有的目标文件

实际上,GNUln -f所做的是在临时名称下创建一个新的符号链接,然后调用renameat,这只是原子地替换目标符号链接。确实如此不是首先删除现有的符号链接。

总的来说,这是可取的,所以不确定为什么man ln撒谎。

在这种情况下,只需结果

那么事情就没有什么不同了。

相关内容