假设,我有一些路径为 %p 的文件,我需要对其进行 gzip 并发送到远程服务器,并且不允许我使用 rsync 和类似的镜像工具。我执行以下操作:
gzip -c -9 %p | ssh user@server "cat > backupPath"
在基本的正常情况下,它工作得很好,但我想知道在文件发送期间与远程服务器的连接失败时会发生什么,因为我想确保文件已完全发送并保存。仅将文件的一部分写入“backupPath”还是遵循“全有或全无”策略 - 即发生错误,不会在远程主机上创建具有“backupPath”地址的文件(这更适合我) ?
答案1
从进程的角度来看,cat
它只是将数据从 stdin 复制到 stdout,并且它根本不知道数据是否完整,特别是数据是否完整。所以你的问题的答案是不这不是一种“全有或全无”的策略。
您可以分两步完成操作,这将使其更加稳健。
#/bin/bash
set -e
set -o pipefail
gzip -c -9 %p | ssh user@server "cat > backupPath.tmp"
ssh user@server "mv backupPath.tmp backupPath"
请注意,这%p
是从原始帖子复制的,它不是 shell 语法。
答案2
看起来下载完成后重命名文件是一个选项,因为重命名是一个原子操作。据我了解,检查 zip 完整性并不能保证文件已完全下载 - 文件的该部分也是正确的 zip 文件的可能性很小。但是,无论如何,我喜欢德鲁本检查完整性以增加安全性的想法。所以,感谢伊卡洛斯和德鲁本的回答,我做出了最终决定:
gzip -c -9 %p | ssh user@server 'set -e; cat > /var/tmp/file.txt.part; gzip -t /var/tmp/file.txt.part; sync /var/tmp/file.txt.part; mv /var/tmp/file.txt.part /var/tmp/file.txt'