从coreutils ln
手册:
通常ln不会删除现有文件。使用--force ( -f ) 选项
无条件删除它们,使用--interactive ( -i ) 选项有条件删除它们,
并使用--backup ( -b ) 选项重命名它们。
$ mkdir output
Run Code Online (Sandbox Code Playgroud)
我可以理解这种失败:
$ ln -sT /etc/passwd output
ln: failed to create symbolic link ‘output’: File exists
Run Code Online (Sandbox Code Playgroud)
但是为什么添加-f
也会失败:
$ ln -sfT /etc/passwd output
ln: ‘output’: cannot overwrite directory
Run Code Online (Sandbox Code Playgroud)
是否-f
覆盖仅是符号链接的现有文件,而不覆盖其他类型的文件(目录、常规文件等)?
可以-T
用来当最后一个参数(即目标文件的说法),是现有目录,意图覆盖目录到链接?
它可以删除文件,但目录不是“文件”。
? lab touch file
? lab mkdir dir
? lab ln -sfT /home file
? lab ln -sfT /home dir
ln: dir: cannot overwrite directory
Run Code Online (Sandbox Code Playgroud)
? lab touch file
? lab mkdir dir
? lab ln -sfT /home file
? lab ln -sfT /home dir
ln: dir: cannot overwrite directory
Run Code Online (Sandbox Code Playgroud)
dest_lstat_ok
boolean 以 false 开始为 true,第一个 if 语句被调用,因为remove_existing_files
由于--force
flag为 true,这反过来允许检查第二个 if 语句。它拒绝删除目录,因为它需要一个文件。
如果您没有设置-T
which 使ln 不将目录视为非目录, ln 只会在目录下创建一个带有源基本名称的符号链接。
在 UNIX 中,目录很特别(我觉得自己在引导来自 SNL 的 The Church Lady)。目录包含其他文件,因此删除它们需要不同的操作。即使目录为空,它仍然有两个文件(.
和..
),因此在目录真正为空并且相关文件的链接计数已更新之前,无法删除目录。
在 UNIX 的早期(我的第一次体验是使用贝尔实验室的第 6 版),常规文件和目录有两个不同的命令(rm
和rmdir
),这反映了它们是两个不同的系统调用的基本事实。 rm
很简单,它只是从目录中删除了您为其命名的条目,并减少了它指向的文件的引用计数(当然,除非引用计数变为 0,否则实际上不会删除该文件)。 rmdir
需要更多(实际上不是在应用程序中,而是在系统调用中),它必须进入目录并找到.
和..
条目,转到那些 inode 并递减引用计数,然后删除父项中的条目并递减该引用计数(与它刚刚递减的相同).
在目录本身中,则应为 0)。所有这些都跨越了几个不同的磁盘扇区,因此必须仔细调整以使 fsck 可以在任何时候恢复中止(即系统崩溃)的可能性。
当然,在更现代的UNIX系统对硬件的限制(即64K字节最大程序的大小,这是一个“K”)得到了缓解,你现在可以做rm -r
并且大部分底层的特殊目录的性质是不太明显,但它仍然存在。我记得需要在第 6 版机器上删除一棵大树,这涉及进入每个目录,删除所有文件,返回到父目录并执行rmdir
并基本上手动完成所有目录树的所有递归。我们确实考虑过一个脚本来帮助解决这个问题,但在那个年代它很少出现,而且非常危险,我们决定要求某人付出所有努力将有助于防止灾难性错误。
您第一次收到“我输入了 ' sudo rm -rf /
' 而不是./
如何恢复的问题?你可能会理解我们为什么要谨慎。