继续MV的最佳实践


13

我使用终端将文件从一个驱动器复制到另一个驱动器。

sudo mv -vi /location/to/drive1/ /location/to/drive2/

但是,在创建目录后,它突然停止了,虽然花了几个小时,但没有错误。

我自己的解决方案通常是哈希和比较的混合,这主要是耗时的混乱,因为我现在必须从中间副本中恢复而实际上不知道丢失了哪些文件(为zsh写了很长的单行代码—请注意,此脚本无法按书面形式在bash中运行):

source_directory="/path/to/source_directory/";
target_directory="/path/to/target_directory/";
while read hash_and_file; do {
    echo "${hash_and_file}" | read hash file;
    echo "${file}" | sed "s/^/${source_directory}/g" | read copy_from;
    echo "${copy_from}" | sed "s/${source_directory}/${target_directory}/g" | read copy_to;
    mv -v "${copy_from}" "${copy_to}" | tee -a log;
    rm -v "${copy_from}" | tee -a log; };
done <<<$(
    comm -23 <( find ${source_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${source_directory}: :g" | sort;
           ) <( find ${target_directory} -type f -exec sha256sum "{}" \; |
                sed "s: ${target_directory}: :g" | sort; ) )

如果名称目标目录或source_directory是路径的一部分,则容易出错,如果由于标记为重复而未移动文件,则将其删除。此外,它也不会最后显示源目录。

是否有最佳实践,如何从被中断的电视中恢复?


我写了一个类似的脚本,它使用cmp了哈希算法。它具有依赖性,并且与while readGilles提到的问题相同。它也是缓慢而冗长的。但是,它比rsync方法更快地释放了磁盘空间,因为文件在运行时会从源中(移出)文件。它可以作为勇敢者的灵感。
joeytwiddle

3
@joeytwiddle rsync提供--delete-during receiver deletes during the transfer了其他一些有用的替代方法:--delete --delete-before --delete-delay --delete-after --delete-excluded。因此,是的,rsync是最好的选择,
艾萨克(Isaac)

我肯定错过了什么。为什么不只是重复相同的mv命令呢?*如果原始源是目录,则可能附加到源路径。
jpa

@isaac不,恐怕rsync --delete*会是一场灾难!它将删除dest当前不在其中的内容src,因此,在上一次尝试中成功移动的所有文件都将被删除!你可能在想的rsync --remove-source-files,我同意是一个很好的选择。(more1更多2
joeytwiddle

@joeytwiddle没有,rsync --delete去除其他不属于源的一部分文件。从[man rsync]()*中删除目标目录中的无关文件*。了解无关的含义:不同步。是的,rsync 提供了一种在正确传输源文件后删除它们的方法。
艾萨克(Isaac)'18

Answers:


46

忘记尝试重新发明rsync并使用rsync了。

sudo rsync -av /location/to/drive1/ /location/to/drive2/

确保在源代码上使用斜杠,否则它将复制到/location/to/drive2/drive1

仔细检查命令是否成功,然后运行rm -rf /location/to/drive1/

上面的命令将覆盖之前存在的任何文件drive2。如果您想提示用户跳过中已有的文件drive2(与一样)mv -i,则更为复杂,因为您现在需要区分已复制的文件和尚未复制的文件。您可以将--ignore-existing选项传递给rsync以跳过目标上已存在的文件,而不管其内容如何。请注意,如果原始mv文件在创建文件的过程中被打断,则该文件将保持其半复制状态(而裸露文件rsync -a将正确完成复制)。

如果您想重现的确切行为(mv -i包括提示),可以这样做,但要复杂得多。

请注意,您的一线班轮非常脆弱。如果文件名包含反斜杠或换行符,则可能无法正确复制它们,或者甚至会欺骗您的脚本删除任意文件。因此除非您确定可以信任文件名不包含反斜杠或换行符,否则请勿使用问题中的代码

为了将来参考,我建议不要将其mv用于大型跨驱动移动,这恰恰是因为很难控制它被中断时会发生什么。使用rsync进行复制,然后删除原始文件。


rsync使mv没有什么承诺?
什么

4
好吧,例如rsync,您做了什么,而mv没有。另外:在不同的机器之间复制;压缩传输;根据基于时间戳或基于哈希的相等性跳过目标处存在的文件;可配置处理所有权,权限,链接和特殊文件;等等。linux.die.net/man
Silly Freak

1
@SillyFreak我应该从中得出结论,我应该始终使用rsync而不是mv,不仅像Gilles所说的那样进行交叉驱动,而且应该进行任何操作,因为“太大”的边界相对主观,如果遇到问题无论如何,它会被rsync解决吗?
什么

9
好吧,当我在一个分区内移动文件或目录时,我通常使用mv(或文件管理器),因为它仅移动对文件/目录的引用。如果我需要进行实际的数据传输,则使用rsync以下条件之一:1)我移动的文件超过了我一眼即可检查是否正确传输的文件;2)我希望我需要保持文件同步;3)我希望传输可能会中断。我的观点是,对于你的问题提出的用例,rsync简直是正确的工具,和mvcp不是。
傻家伙

7
我建议始终先使用-v和-dry-run运行任何rsync命令,以确认其确切作用。
达伦(Darren)'18
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.