来自核心工具 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 版),对于常规文件和目录有两个不同的命令 (rm
和rmdir
),这反映了它们是两个不同系统调用的根本事实。 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 只会在目录下使用源的基本名称创建一个符号链接。