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

Tim*_*Tim 11 linux coreutils mv

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

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

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

Bow*_*Red 10

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

如果您还没有imperative_PLs/fortranmv则将采用现有fortran目录并将其重命名为树中的那个点。

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

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

把它想象成rename相反,这种行为似乎更容易理解。


roa*_*ima 7

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

    • 移动到相同的文件系统:(rename最初linkunlink
    • 跨文件系统移动:递归文件复制,然后递归 unlink
  2. 观点:我认为这是没有这么多,它的目的不是工作,因为它不是设计来处理这个用例。对于旨在做好一件事的“简单”工具,您需要提供一组开关来指示要mv采取哪些操作路径:

    • 以错误保释,如在当前实现中
    • 合并,如果文件已经存在,则抛出错误
    • 合并,替换任何已经存在的目标文件

如果合并/替换操作是你想要什么,你可以实现很容易用足cp后跟rm,或者通过使用复制实用程序文件树中的一个tarpax等等。


jll*_*gre 7

mv实际上是rename在掩护下。

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

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

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