我使用终端将文件从一个驱动器复制到另一个驱动器。
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; ) )
如果名称 target directory 或 source_directory 是路径的一部分,这很容易出错,如果文件由于被标记为重复而未被移动,则删除文件。最后它也没有源目录。
是否有最佳实践如何从中断的 mv 中恢复?
忘记尝试重新发明 rsync,并使用 rsync。
确保在源文件上使用尾部斜杠,否则它会复制到
/location/to/drive2/drive1
.仔细检查命令是否成功,然后运行
rm -rf /location/to/drive1/
.上面的命令将覆盖任何预先存在的文件
drive2
。如果您想提示用户跳过 中已存在的文件drive2
,如mv -i
,则更复杂,因为您现在需要区分已复制的文件和尚未复制的文件。您可以将--ignore-existing
选项传递给 rsync 以跳过目标上已存在的文件,无论其内容如何。请注意,如果原始mv
文件在创建文件的过程中被中断,则该文件将保持半复制状态(而裸文件rsync -a
将正确完成复制)。如果您想重现 的确切行为
mv -i
,包括提示,可以这样做,但要复杂得多。请注意,您的巨型班轮非常脆弱。如果文件名包含反斜杠或换行符,它们可能无法正确复制,甚至可能会欺骗您的脚本删除任意文件。因此,除非您确定可以信任文件名不包含反斜杠或换行符,否则请勿使用问题中的代码。
为了将来参考,我建议永远不要使用
mv
大的交叉驱动器移动,正是因为如果它被打断,很难控制会发生什么。使用 rsync 进行复制,然后删除原件。