备份任务显示成功,压缩包却没内容?备份命令与压缩工具通过管道相连时,Bash 默认报告最后一段的退出码。先用无副作用的示例确认现象,再改真实脚本。

用两条空命令重现退出码差异
在 Bash 子进程执行bash -c 'set +o pipefail; false | true; echo $?',按默认规则预期显示 0。另用单引号写成bash -c 'set -o pipefail; false | true; echo $?',预期显示 1。这里只验证 Shell 的退出码,没有运行备份。
让管道暴露上游失败
在确认脚本确实由 Bash 执行后,在入口启用set -o pipefail。开启后,管道返回最右侧非零退出码,全部成功才返回零。不应假设以 sh 启动的所有环境都支持这个选项。核对定时任务实际调用方式。
保存每一段的退出状态
在没有 errexit 提前退出的诊断环境中运行false | true,紧接着执行codes=("${PIPESTATUS[@]}")保存分段状态。在保存前执行 echo 等其他命令会覆盖 PIPESTATUS。记录报错段与 stderr,才能知道应修备份还是压缩。
避免把残缺归档当成新备份
实际任务宜先写到同一文件系统内的临时文件,只在管道成功、压缩完整性和应用级恢复检查通过后切换成品。压缩包能解压,不能证明上游备份完整。失败时保留上一份已验证备份。
同时验证成功与失败两条路径
可在萤光云或LightNode的独立实例演练。令备份源不可读或模拟上游失败,确认任务返回非零、告警出现、旧文件未被替换。再用有效输入验证归档可恢复。管道有意提前结束时,也要分辨 SIGPIPE 是否符合预期。
FAQ
只打开 set -e 就够吗? 默认不改变管道的状态规则。
pipefail 会立即终止整条管道吗? 它定义管道结果,不能当作主动终止其他进程的机制。
为什么不能先打印 $?? 打印命令会更新后续可见的 PIPESTATUS。
压缩测试通过就能恢复吗? 仍需用实际应用验证源数据。
应边调试边覆盖生产备份吗? 建议先在隔离路径运行。
温馨提示
不要在共享环境开启会打印密码的脚本跟踪。涉及凭据的备份诊断只记录必要的错误和退出码。


