我想通过 ssh 移动大量大文件。
因为我想释放空间,所以我想在移动文件后将其删除。由于数据量很大,我希望能够随时中断传输并稍后使用相同的命令继续传输。 (事实上,我的互联网连接每天至少重置一次并中断传输)
不幸的是,我不能使用 rsync,至少不能像这样:
rsync -avz --remove-source-files user@source:/path/ /destination_path/
rsync 仅在复制所有文件后删除源文件 - 如果传输中断,则根本不会释放任何空间。如果不手动删除已复制的文件,将命令放入 cron 将导致它永远无法完成。
这个问题有解决办法吗?
答案1
如果您无法使用rsync
,并且只想在成功复制每个文件后才删除源文件,则可以对逐个目录、逐个文件传输执行如下操作:
if cd /path/to/files; then
for file in *; do
if scp -pr "$file" [email protected]:/destination/files/"$file"; then
rm -fr "$file"
else
echo "Transfer of '$file' failed. Not removing local copy." 1>&2
fi
done; fi
如果您想在删除本地文件之前进行额外的健全性检查,则可以添加一致性检查,但这会减慢非常大的文件的速度,并且这种快速而肮脏的校验和仅适用于文件;不是目录:
if cd /path/to/files; then
for file in *; do
if scp -pr "$file" [email protected]:/destination/files/"$file"; then
if [[ "$(md5sum < "$file" )" = "$( ssh [email protected] md5sum < /destination/files/"$file" )" ]]; then
rm -fr "$file"
else
echo "Unable to validate remote '$file'. Not removing local copy" 1>&2
fi
else
echo "Transfer of '$file' failed. Not removing local copy." 1>&2
fi
done; fi
答案2
rsync 仅在复制所有文件后删除源文件
这是一个错误的前提。当您只有几个大文件时,这似乎是正确的,但在一般情况下肯定不是这样。
rsync
一旦文件成功传输,该命令就会将删除指令放入队列。然而,由于指令与其他数据复用,因此可能需要“一段时间”才能在源端应用删除。
如果您运行rsync
大量文件,您将看到在所有传输完成之前源上的文件已被删除。 (我rsync
在一个会话中运行了数万甚至数十万个文件,我确实看到了这种行为。)
此外,如果您遇到传输中断的情况,则rsync
重新启动时,它将删除之前成功传输的文件,然后再继续传输下一组文件。 (我也看到了这种行为。)
考虑https://superuser.com/a/405795/332907参考源代码作为证据。