使用cp命令的--update(-u)选项时为何会删除目标目录中的文件?
嘿,这个疑惑太正常了——毕竟从你贴出的man手册片段来看,-u(也就是--update=older)看起来只应该替换目标里比源文件旧的文件,怎么会平白无故出现删除操作呢?
你提到的man手册片段是这样的:
--update[=UPDATE]
control which existing files are updated;
UPDATE={all,none,none-fail,older(default)}.-u equivalent to --update[=older]. See below
UPDATE controls which existing files in the destination are
replaced. 'all' is the default operation when an --update option
is not specified, and results in all existing files in the
destination being replaced. 'none' is like the --no-clobber
option, in that no files in the destination are replaced, and
skipped files do not induce a failure. 'none-fail' also ensures
no files are replaced in the destination, but any skipped files
are diagnosed and induce a failure. 'older' is the default
operation when --update is specified, and results in files being
replaced if the...
这段内容没写完,完整的--update=older规则里,除了比较文件的修改时间,还有一个关键条件:当源目录中的条目和目标目录中的同名条目类型不一致时,cp会触发替换操作,而这种替换往往需要先删除目标里的现有内容:
- 举个常见的场景:如果源目录里的
path/file原本是普通文件,后来你把它改成了符号链接(反过来也一样,源是符号链接,目标是普通文件),这时候两者类型不匹配,哪怕目标文件的修改时间比源新,cp -ruv也会尝试替换它,替换前就会先删除目标里的/mnt/destinationdir/path/file。 - 另一种情况:如果源里的
path/file被改成了目录,那cp要在目标里创建这个目录,就必须先删掉目标里现有的同名文件,这也会弹出删除提示。
你可以验证一下:下次再看到这个提示时,用ls -ld sourcedir/path/file和ls -ld /mnt/destinationdir/path/file分别查看源和目标条目的类型,肯定能发现两者不一样(比如一个是-普通文件,一个是l符号链接,或者一个是d目录)。
另外补充一点:cp -r本身默认不会删除目标中源里没有的文件,只有当你加上--delete参数时才会同步删除,但上面说的类型不匹配导致的删除,是替换操作的必要步骤,和--delete的逻辑完全不同。
备注:内容来源于stack exchange,提问作者Joce

