继续 mv 的最佳实践

Wha*_*hat 13 data-recovery mv

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

sudo mv -vi /location/to/drive1/ /location/to/drive2/
Run Code Online (Sandbox Code Playgroud)

然而,在创建目录后,它突然停止了,几个小时后,并且没有错误。

我自己的解决方案通常是散列和比较的混合,这主要是一个耗时的混乱,因为我现在必须从中间副本中恢复而不真正知道丢失了哪些文件(为 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; ) )
Run Code Online (Sandbox Code Playgroud)

如果名称 target directory 或 source_directory 是路径的一部分,这很容易出错,如果文件因为被标记为重复而未被移动,则删除它们。它最终也没有源目录。

是否有最佳实践如何从中断的 mv 中恢复?

Gil*_*il' 46

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

sudo rsync -av /location/to/drive1/ /location/to/drive2/
Run Code Online (Sandbox Code Playgroud)

确保在源上使用尾部斜杠,否则它会复制到/location/to/drive2/drive1.

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

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

如果您想重现 的确切行为mv -i,包括提示,则可以完成,但要复杂得多。

请注意,您的单巨型衬垫非常脆弱。如果文件名包含反斜杠或换行符,则它们可能无法正确复制,甚至可能会诱使您的脚本删除任意文件。因此除非您确定可以相信文件名不包含反斜杠或换行符,否则不要使用问题中的代码

为了将来参考,我建议永远不要mv用于大型交叉驱动移动,正是因为很难控制如果它被中断会发生什么。使用 rsync 进行复制,然后删除原件。

  • 好吧,当我在一个分区内移动文件或目录时,我通常使用 `mv`(或文件管理器),因为它只移动对文件/目录的引用。如果我需要进行实际的数据传输,那么如果满足以下任一条件,我将使用 `rsync`: 1) 我移动的文件多于我一目了然检查正确传输的能力;2) 我预计我需要保持文件同步;3) 我预计传输可能会中断。我的观点是,对于您在问题中提出的用例,`rsync` 只是正确的工具,而 `mv` 或 `cp` 不是。 (9认同)
  • 我建议总是先使用 -v 和 —dry-run 运行任何 rsync 命令,以确认它到底要做什么。 (7认同)
  • 好吧,例如 `rsync` 会做你想做的事情,而 `mv` 不会。还有:在不同机器之间复制;传输压缩;基于时间戳或基于哈希的相等性跳过目标中存在的文件;所有权、权限、链接和特殊文件的可配置处理;等 https://linux.die.net/man/1/rsync (4认同)