如何重复调用 rsync 直到文件成功传输

Bru*_*pes 34 linux bash rsync

我正在尝试从不可靠的远程服务器同步文件,这意味着连接往往会“随机”失败

rsync:连接意外关闭

rsync 是用 --partial 调用的,所以我希望能够在循环中调用 rsync 直到文件完全传输。似乎没有告诉 rsync 重试的标志。

编写脚本的最佳方法是什么?bash for 循环?

Dav*_*vid 35

如果您在一次同步中同步所有内容,请循环调用 rsync,直到 rsync 为您提供成功的返回码。

就像是:

RC=1 
while [[ $RC -ne 0 ]]
do
   rsync -a .....   
   RC=$?
done
Run Code Online (Sandbox Code Playgroud)

这将循环调用 rsync,直到它给出返回码 0。您可能希望在其中添加睡眠以防止对您的服务器进行 DOS 攻击。

  • 你可以写一会儿!rsync -a .... ;do sleep 5;done (35认同)
  • 如果存在非暂时性错误(例如读取或写入文件的权限错误),这将变成无限循环。我建议检查 rsync 的退出状态是否有特定的网络错误,比如 `RC=12; 而 [[ $RC -eq 12 || $RC -eq 30 ]]`(或您从网络掉线看到的任何退出状态)。 (4认同)
  • 遗憾的是 rsync 没有内置此功能,因为在自动身份验证不可用或不合适的情况下,任何基于 shell 的循环都会提示输入密码。 (3认同)

Ian*_*ung 12

不久前我遇到了同样的问题。最后,我写了一些类似于 David 的答案,但用最大重试次数对它进行了一些修改,响应 Ctrl-C,例如:http : //blog.iangreenleaf.com/2009/03/rsync-and-retrying-直到-we-get-it.html

显而易见的解决方案是检查返回值,如果 rsync 返回成功以外的任何内容,请再次运行它。这是我的第一次尝试:

while [ $? -ne 0 ]; do rsync -avz --progress --partial /rsync/source/folder backupuser@backup.destination.com:/rsync/destination/folder; done
Run Code Online (Sandbox Code Playgroud)

这样做的问题是,如果您想停止程序,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 backupuser@backup.destination.com:/rsync/destination/folder
done

if [ $i -eq $MAX_RETRIES ]
then
  echo "Hit maximum number of retries, giving up."
fi
Run Code Online (Sandbox Code Playgroud)


小智 9

用 sshpass 将所有内容放在一起

while ! sshpass -p 'xxxx' \
  rsync --partial --append-verify --progress \
  -a -e 'ssh -p 22' /source/ remoteuser@1.1.1.1:/dest/; \
  do sleep 5;done
Run Code Online (Sandbox Code Playgroud)