为什么 mv 不能处理目标中存在同名目录?

为什么 mv 不能处理目标中存在同名目录?

mv无法将目录移动到具有同名目录的目标:

$ mv fortran/ imperative_PLs/
mv: cannot move ‘fortran/’ to ‘imperative_PLs/fortran’: Directory not empty
  1. 为什么mv在这种情况下不起作用?可以从系统调用来解释吗mv? (比较一下rsync可以)

  2. 为什么mv设计在这种情况下不起作用?其理由或要点是什么?

答案1

mv并且rsync不是类似的程序。特别是,mv经常尝试简单地重命名对象。如果它位于同一文件系统中,则它根本不复制内容。

如果您还没有imperative_PLs/fortran,那么mv将采用现有fortran目录并将其重命名为树中的该点。

但是您在该位置已经有一个目录(包含内容)。由于名称只能引用单个对象,因此必须删除或重命名现有目录。 mv假设您不想执行任何操作并中止。

rsync相反,复制其中的各个文件和其他内容fortran并将它们放入现有imperative_PLs/fortran目录中。

相反rename,这种行为似乎更容易理解。

答案2

  1. mv在这种情况下不起作用,因为它的设计目的不是这样做。系统调用(可能)是

    • 移动到相同的文件系统:(rename原来linkunlink
    • 跨文件系统移动:递归文件复制,然后递归unlink
  2. 意见:我认为这与其说是设计的,不如说是设计的不是工作,因为它不是为处理这个用例而设计的。对于一个旨在做好一件事的“简单”工具,您需要提供一组开关来指示mv要采取以下哪一个操作路径:

    • 出现错误时退出,如当前实施中所示
    • 合并时,如果文件已存在则抛出错误
    • 合并,替换任何已存在的目标文件

cp如果合并/替换操作是您想要的,您可以使用后跟rm或使用文件树复制实用程序之一来轻松实现它tarpax等等。

答案3

mv实际上是rename在幕后。

如果将一个文件移动到另一个文件,mv则假设您知道自己在做什么并覆盖目标文件。

如果将一个目录移动到另一个目录,mv则假设您要保留原始目录的基本名称并在目标目录上创建它。如果目标端尚不存在具有该名称的目录,或者具有该名称的目录存在但为空,则操作成功。

但是,如果目标目录已经存在并且不为空,则这不再是一个,rename而是应该是递归文件和目录删除。rename不是设计来这样做的,所以它失败了,mv不会进一步,因为它假设你不想这样做并且也失败了。

答案4

如果你想用另一个目录替换里面的内容,你可以使用

mv --backup=simple src dest

这会将 重命名destdest~并将 移动srcdest

相关内容