通过 ssh 可靠地移动(而不是复制)文件

通过 ssh 可靠地移动(而不是复制)文件

我想通过 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参考源代码作为证据。

相关内容