我刚刚将49GB目录“ mv”到错误的文件路径,是否可以恢复文件的原始状态?


58

我有一个(好吧,我一个)目录:

/media/admin/my_data

它的大小约为49GB,其中包含成千上万个文件。该目录是活动LUKS分区的安装点。

我想将目录重命名为:

/media/admin/my_data_on_60GB_partition

当时我没有意识到,但是我从主目录发出了命令,所以我最终做了:

~% sudo mv /media/admin/my_data my_data_on_60GB_partition

因此,mv程序开始将/media/admin/my_data其内容移至新目录~/my_data_on_60GB_partition

我使用Ctrl+ C来取消命令的整个过程,所以现在我有一堆文件分散在目录中:

~/my_data_on_60GB_partition    <---  about 2GB worth files in here

/media/admin/my_data           <---- about 47GB of orig files in here    

新目录~/my_data_on_60GB_partition及其某些子目录由root拥有。
我假设mv程序必须首先以root用户身份复制文件,然后在传输之后将chown它们重新复制到我的用户帐户。

我的目录/分区备份有些旧。
我的问题是,是否可以可靠地还原一堆被移动的文件?

也就是说,我可以运行:

sudo mv ~/my_data_on_60GB_partition/*  /media/admin/my_data

还是我应该放弃尝试恢复,因为文件可能已损坏并部分完成等?

  • 操作系统-Ubuntu 16.04
mv --version  
mv (GNU coreutils) 8.25

36
在恐慌中键入Control-Z(暂停)而不是时,养成习惯Control-C。在这种情况下,您将能够看到当时正在传输的文件,从而知道哪个文件仅被部分复制。然后,您可以冷静地决定如何进行。(kill -stop用于不在tty中的进程)。
meuh

1
2GB + 47GB = 60GB ???
tbodt

7
@tbodt (2GB + 47GB) < 60GB。分区容量为60GB,文件夹及其内容的大小为49GB。
the_velour_fog

Answers:


87

在文件系统之间移动文件时,mv请勿在完成复制之前删除文件,而是按顺序处理文件(我最初说是先复制然后依次删除每个文件,但这并不能保证-至少GNU mv副本然后删除每个命令-依次使用line参数,而POSIX指定此行为)。因此,目标目录中最多应有一个不完整的文件,而原始文件仍将位于源目录中。

要将其移回,请添加该-i标志,这样mv就不会覆盖任何内容:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

(假设您没有要从中还原的任何隐藏文件~/my_data_on_60GB_partition/),或者更好的情况是(鉴于您发现的那样,您可能有许多文件要删除),请添加该-n标记,这样mv不会覆盖任何内容,但不会向您询问:

sudo mv -n ~/my_data_on_60GB_partition/* /media/admin/my_data/

您还可以添加-v标志以查看正在执行的操作。

使用任何兼容POSIX的mv目录,原始目录结构仍应保持完整,因此您也可以检查一下-并简单地删除/media/admin/my_data...(不过,在一般情况下,我认为该mv -n变体是安全的方法-它可以处理各种形式的mv,包括例如 mv /media/admin/my_data/* my_data_on_60GB_partition/。)

您可能需要还原一些权限;你可以这样做集体使用chownchmod,或使用从备份中恢复它们getfaclsetfacl(感谢佐藤桂提醒)。


谢谢斯蒂芬·基特(Stephen Kitt),那是很大的帮助!我可以find用来查找和设置权限。新目录中有很多文件名中有空格,但没有隐藏文件,据我所知。您是否认为命令中的glob sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/会扩展文件名而不会出现单词拆分问题?我在想是否可以使用sudo rsync ~/my_data_on_60GB_partition/ /media/admin/my_data/我认为可以处理带空格的文件路径?
the_velour_fog

6
可以肯定的是,当描述OP之类的事情发生时,我改用了rsync它,因此它还将检查所有文件的完整性。但是很高兴知道我不需要那个。
Hauleth '16

1
@the_velour_fog通配符可以毫无问题地处理文件名中的空格。
史蒂芬·基特

5
如果某些(古怪的)管理员将“ mv”设为在系统级别执行“ mv -f” 的功能(即/ etc / profile或此类系统范围的文件),则我希望su command mv -i ...(或su /bin/mv -i ...)而不是)。 。命令内容:启动命令,而不是名称相同的函数或别名。(例如:可能很不幸,并且在总是源文件中有一个(非常非常糟糕!) ,然后“ rm -i something”不会询问任何内容(只是抗议“ -i “文件不存在!)... [我已经看到这样的东西了…… 颤抖 ]sudo mv -i ...function mv { /bin/mv -f -- "$@" }
奥利维尔·杜拉克

3
@OlivierDulac-一个很好的例子,说明为什么使用别名或与标准程序同名的脚本是不好的做法。

19

得到斯蒂芬·基特(Stephen Kitt)的回答并讨论此命令作为潜在解决方案后:

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

我决定推迟运行它,直到我对发生的事情有所了解,这个答案描述了我发现并最终完成的事情。

我正在使用mv将文件复制到目标的Gnu ,然后只有复制操作成功,它才会删除原始文件。
但是,我想确认是否一次mv执行一个序列的操作,如果是的话,原始文件夹的内容将被清晰地切成两部分,一部分移到目标位置,另一部分仍留在源文件中。可能会有一个文件在复制过程中被打断,这在两个目录之间将很常见-并且可能格式错误。

为了发现两个目录之间共有的文件,我运行了:

~% sudo diff -r --report-identical-files my_data_on_60GB_partition/. /media/admin/mydata/. | grep identical | wc -l
14237

结果表明,在源目录和目标目录中都有14237个相同文件的实例,我通过手动检查文件来确认-是的,两个目录中都有许多相同的文件。这表明只有在mv复制大量文件后,它才执行源文件的删除。显示了infomv命令的快速查找

它[ mv]首先使用一些用于cp -a复制请求的目录和文件的相同代码,然后(假设复制成功)将其删除。如果复制失败,那么将删除复制到目标分区的部分。

我没有运行命令,但怀疑是否尝试运行

sudo mv -i ~/my_data_on_60GB_partition/* /media/admin/my_data/

-i 覆盖之前提示可能已触发14,000次以上。

因此,找出新创建的目录中的文件总数:

~% sudo find my_data_on_60GB_partition/ -type f -a -print | wc -l                                                                    
14238

因此,如果新目录中总共有14238个常规文件,而源中有14237个原始文件,则意味着新目录中只有一个文件,而源中没有相应的相同文件。为了弄清楚那个文件是什么,我朝着源的方向运行了rsync:

~% sudo rsync -av --dry-run my_data_on_60GB_partition/ /media/admin/my_data
sending incremental file list
./
Education_learning_reference/
Education_learning_reference/Business_Education/
Education_learning_reference/Business_Education/Business_education_media_files/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/
Education_learning_reference/Business_Education/Business_education_media_files/Jeff Hoffman - videos/Jeff and David F interview/018 business plans-identifying main KPIs.flv

sent 494,548 bytes  received 1,881 bytes  330,952.67 bytes/sec
total size is 1,900,548,824  speedup is 3,828.44 (DRY RUN)

快速检查确认这是格式错误的文件,该文件在源和目标上均存在,目标文件= 64MB,原始文件= 100MB。该文件及其目录层次结构仍由root拥有,并且尚未还原原始权限。

因此,总而言之:

  • 所有mv从未到达的文件 仍返回其原始位置(显然)
  • 所有mv完全复制的文件仍在源目录中保留其原始副本
  • 仅部分复制的文件仍将原始文件放回源目录中

换句话说,所有原始文件仍然完好无损,在这种情况下,解决方案是简单地删除新目录!


哇...我已经更新了答案,-n一般情况下会更好。我检查了mv源代码,它一次删除了源一个参数。
史蒂芬·基特

@StephenKitt很好啊。我想知道何时mv删除源代码。因此,该命令mv foo bar bazfoo先删除baz/foo 然后删除原始文件,foo然后再移动barbaz/bar.. ??
the_velour_fog

是的,这是正确的; 实际上,这就是POSIX所指定的(基本上是这样,任何影响任何源参数的错误都将完整保留整个源层次结构)。
史蒂芬·基特

我认为您也可以使用diff查找一个未完成的文件。
StarWeaver

1
您应该使用cmp而不是diff比较二进制文件。另外,上面的讨论仅在跨不同文件系统移动文件时才有意义。在同一文件系统中移动文件时不涉及复制。

4

我只是以为我会评论说,有些人可能很想将“ xargs”扔进来以并行运行方式。那给了我勇气,我真的很喜欢上面的rsync解决方案。

至于有关移动和复制的文件系统方面的信息,以及何时删除原始文件,VFS和基础文件系统将协调以确保每个文件的原子性,然后再执行删除步骤。因此,即使在完全写入目标文件之前将其中断,VFS中的所有锁定都是严格严格的,即使在并行情况下,也可以防止诸如随机数据交织之类的事情。(我从事Linux VFS和NFS4的工作)

在混合文件中添加“ xargs”可能会使双重健全性检查步骤变得头痛,因为在传输过程中有多个文件。我希望我能有更多的系统级脚本。好提醒我!

喜欢这个问题,对蜘蛛网有好处,让我再次喜欢rsync。干杯!


1
更不用说文件名包含空格时的麻烦了。
2016年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.