为什么mv比cp快那么多?如何从错误的 mv 命令中恢复?

为什么mv比cp快那么多?如何从错误的 mv 命令中恢复?

我在 FileZilla 中错误地将一个文件夹拖放到另一个文件夹中。

~/big_folder
~/some_other_folder

移动的文件夹非常大。它包括数十万个文件(node_modules、小图像文件、大量文件夹)

奇怪的是,当我松开鼠标后,移动就完成了。文件夹“big_folder”被移至“some_other_folder”。

~/some_other_folder/big_folder

big_folder(搬家后没有~/)

然后我意识到错误并尝试返回,但在 FileZilla 和终端上都失败了。

然后我必须cp -r将文件复制回来,因为有服务器端代码访问这些文件~/big_folder

而且需要永远等待......

我应该怎么办?

顺便说一句,这是 FileZilla 的输出(这是移回失败的结果):

Status:       Renaming '/root/big_folder' to '/root/some_other_folder/big_folder'
Status:       /root/big_folder -> /root/some_other_folder/big_folder

Status:       Renaming '/root/some_other_folder/big_folder' to '/root/big_folder'
Command:  mv "big_folder" "/root/big_folder"
Error:          mv /root/some_other_folder/big_folder /root/big_folder: received failure with description 'Failure'

答案1

如果一个目录是搬家了在同一个文件系统(同一个分区)内,那么只需重命名目录的文件路径即可。除了目录本身的目录条目之外,无需更改任何数据。

什么时候复制目录中,每个文件的数据都需要复制。这涉及读取所有源数据并将其写入目标。

移动目录之间文件系统涉及将数据复制到目标并将其从源中删除。这将花费与在单个文件系统中复制(复制)数据一样长的时间。


如果 FileZilla 成功地将目录从~/big_folderto重命名~/some_other_folder/big_folder,那么我将使用

mv ~/some_other_folder/big_folder ~/big_folder

...首先确保没有被调用的目录~/big_folder(如果有,则移动会将其作为子文件夹放入该目录big_foldersome_other_folder) 。~/big_folder

答案2

现有的答案很好,但我想通过准确地展示移动和复制文件时发生的情况来对其进行一些扩展。当您在复制期间查看系统调用时,您会看到:

open("hello1.txt", O_RDONLY)               = 3
open("hello2.txt", O_WRONLY|O_CREAT, 0644) = 4
read(3, "Hello, world!\n", 4096)           = 14
write(4, "Hello, world!\n", 14)            = 14
close(3)                                   = 0
close(4)                                   = 0

这将打开源文件,然后创建第二个文件。然后,它将源文件的内容读取到内存中,并将该内存写入目标文件。这需要多次上下文切换和一些磁盘 I/O,这对于大文件来说可能相当高。但是,如果您移动文件,您会看到:

rename("hello1.txt", "hello2.txt")         = 0

请务必记住,只有当文件位于同一物理磁盘上的同一文件系统上时,您才会看到该文件被重命名。如果您创建一个巨大的数千兆字节文件,然后将其在家中的两个位置之间移动,您会发现该操作立即完成。另一方面,如果您将其移动到外部设备,则移动所需的时间与您使用的设备一样长cp。系统调用跟踪将与第一个相同,但在unlink("hello1.txt")最后。这是因为只有当源和目标位于同一文件系统上时,重命名才能用于移动文件。

相关内容