`ln -sf` 是否覆盖仅是符号链接的现有文件

`ln -sf` 是否覆盖仅是符号链接的现有文件

来自核心工具 ln手动的:

通常情况下不删除现有文件。使用- 力量-F)无条件删除它们的选项
- 交互的-我) 有条件地删除它们的选项,
以及--备份-b) 重命名它们的选项。

$ mkdir output

我可以理解这个失败:

$ ln -sT /etc/passwd output
ln: failed to create symbolic link ‘output’: File exists

但为什么添加-f 失败:

$ ln -sfT /etc/passwd output
ln: ‘output’: cannot overwrite directory

是否-f 覆盖仅是符号链接的现有文件,而不是其他类型的文件(目录、常规文件...)?

当最后一个参数(即目标文件参数)是现有目录时可以-T使用,目的是将该目录覆盖为链接吗?

答案1

在 UNIX 中,目录是特别的(我觉得自己在引导《周六夜现场》中的教堂女士)。目录包含其他文件,因此删除它们需要不同的操作。即使目录为空,它仍然有两个文件(...),因此在目录真正为空并且相关文件的链接计数已更新之前,无法删除目录。

在 UNIX 的早期(我的第一次体验是贝尔实验室的第 6 版),对于常规文件和目录有两个不同的命令 (rmrmdir),这反映了它们是两个不同系统调用的根本事实。 rm很简单,它只是从目录中删除了您为其指定名称的条目,并减少了它指向的文件的引用计数(当然,除非引用计数变为 0,否则文件实际上并没有被删除)。 rmdir需要更多(实际上不是在应用程序中,而是在系统调用中),它必须进入目录并找到...条目,转到这些 inode 并递减引用计数,然后删除父级中的条目并递减引用计数(与目录本身中刚刚减少的引用计数相同.,此时应该为 0)。所有这些都跨越几个不同的磁盘扇区,因此必须仔细调整,以使 fsck 可以在任何时候恢复中止(即系统崩溃)的可能性。

当然,在更现代的 UNIX 系统中,硬件的限制(即 64Kbyte 最大程序大小,“K”)已得到缓解,您现在可以执行以下操作rm -r很多潜在的事情特别的目录的性质不太明显,但它仍然存在。我记得需要删除第六版机器上的一棵大树,其中涉及进入每个目录,删除所有文件,返回父级并手动rmdir执行所有目录树的所有递归操作。我们确实考虑过一个脚本来帮助解决这个问题,但当时它很少出现,而且它非常危险,因此我们决定要求某人付出所有努力将有助于防止灾难性错误。

当您第一次收到这样的问题:“我输入了‘ sudo rm -rf /’而不是./我该如何恢复?”你可能会理解我们为什么如此谨慎。

答案2

它可以删除文件,但目录不是“文件”。

➜  lab touch file        
➜  lab mkdir dir
➜  lab ln -sfT /home file
➜  lab ln -sfT /home dir 
ln: dir: cannot overwrite directory

这见于来源:

  if (remove_existing_files || interactive || backup_type != no_backups)
    {
      dest_lstat_ok = (lstat (dest, &dest_stats) == 0);
      if (!dest_lstat_ok && errno != ENOENT)
        {
          error (0, errno, _("failed to access %s"), quoteaf (dest));
          return false;
        }
    }
[...]
  if (dest_lstat_ok)
    {
      if (S_ISDIR (dest_stats.st_mode))
        {
          error (0, 0, _("%s: cannot overwrite directory"), quotef (dest));
          return false;
        }
      if (interactive)
        {
          fprintf (stderr, _("%s: replace %s? "), program_name, quoteaf (dest));
          if (!yesno ())
            return true;
          remove_existing_files = true;
        }

dest_lstat_ok从 false 开始的 boolean 变为 true,调用第一个 if 语句因为remove_existing_files是真的,因为--force标志,这又允许检查第二个 if 语句。它拒绝删除目录,因为它期望文件

如果您不设置-T使得ln 不将目录视为非目录, ln 只会在目录下使用源的基本名称创建一个符号链接。

相关内容