我正在尝试从不可靠的远程服务器同步文件,这意味着连接往往会“随机”失败
rsync:连接意外关闭
Rsync 是用 --partial 调用的,所以我想能够循环调用 rsync,直到文件完全传输完毕。似乎没有标志来告诉 rsync 重试。
编写脚本的最佳方法是什么? bash for 循环?
答案1
如果您要在一次同步中同步所有内容,请循环调用 rsync,直到 rsync 返回成功的返回代码。
就像是:
RC=1
while [[ $RC -ne 0 ]]
do
rsync -a .....
RC=$?
done
这将循环调用 rsync,直到它给出返回代码 0。您可能需要在其中添加一个 sleep 以防止对您的服务器进行 DOS 攻击。
答案2
不久前我也遇到过同样的问题。最后我写了一些类似于 David 的答案的东西,但稍微改进了一下,增加了最大重试次数、响应 Ctrl-C 等:http://blog.iangreenleaf.com/2009/03/rsync-and-retrying-until-we-get-it.html。
显而易见的解决方案是检查返回值,如果 rsync 返回任何非成功值,则再次运行它。这是我的第一次尝试:
while [ $? -ne 0 ]; do rsync -avz --progress --partial /rsync/source/folder [email protected]:/rsync/destination/folder; done
问题是,如果你想要停止程序,Ctrl-C 只会停止当前的 rsync 进程,而循环会立即启动另一个进程。更糟糕的是,我的连接不断中断,以至于 rsync 在出现连接问题时会以与 SIGINT 相同的“未知”错误代码退出,所以我无法让循环在需要时区分和中断。这是我的最终脚本:
#!/bin/bash
### ABOUT
### Runs rsync, retrying on errors up to a maximum number of tries.
### Simply edit the rsync line in the script to whatever parameters you need.
# Trap interrupts and exit instead of continuing the loop
trap "echo Exited!; exit;" SIGINT SIGTERM
MAX_RETRIES=50
i=0
# Set the initial return value to failure
false
while [ $? -ne 0 -a $i -lt $MAX_RETRIES ]
do
i=$(($i+1))
rsync -avz --progress --partial /rsync/source/folder [email protected]:/rsync/destination/folder
done
if [ $i -eq $MAX_RETRIES ]
then
echo "Hit maximum number of retries, giving up."
fi
答案3
使用 sshpass 将所有东西整合在一起
while ! sshpass -p 'xxxx' \
rsync --partial --append-verify --progress \
-a -e 'ssh -p 22' /source/ [email protected]:/dest/; \
do sleep 5;done
答案4
另一种做法是——一个简单的一行程序,无限期地运行直到成功,失败后有 1 秒的延迟。
while true; do rsync -avz --info=progress2 --partial src/ dsr/ && break || sleep 1; done
下面是稍微修改一下,将失败次数限制为 10 次。
for i in {0..10}; do rsync -avz --info=progress2 --partial src/ dsr/ && break || sleep 1; done