在我的bash脚本中,如果rsync
在放弃之前失去了与目标的连接,我会尝试让它重试10次。
我知道这段代码会捕获所有错误,但我现在可以接受。
我的代码是:
lops="0"
while true; do
let "lops++"
rsync $OPT $SRCLINUX $TRG 2>&1 | tee --append ${LOGFILE}
if [ "$?" -eq "0" ]; then
echolog "rsync finished WITHOUT error after $lops times"
break
else
echolog "Re-starting rsync for the ${lops}th time due to ERRORS"
fi
if [[ "$lops" == "10" ]]; then
echolog "GAVE UP DUE TO TOO MANY rsync ERRORS - BACKUP NOT FINISHED"
break
fi
done
它没有按预期工作,以下是第一个错误发生的情况:
TDBG6/
rsync: connection unexpectedly closed (131505 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at io.c(226) [sender=3.1.1]
rsync finished WITHOUT error after 1 times
这是因为$吗?包含tee
的返回值,而不是rsync
?
我该怎么解决这个问题?(我个人受Linux语法限制:)
我认为至少有两种可能性可以解决您的问题:
-
使用
PIPESTATUS
:一个数组变量,包含最近执行的前台管道(可能只包含一个命令)中进程的退出状态值列表。
用作:
rsync $OPT $SRCLINUX $TRG 2>&1 | tee --append ${LOGFILE} if (( PIPESTATUS[0] == 0 )); then
-
使用
rsync
的--log-file
选项。
注:
- 您的代码中缺少许多引号
- 不要使用大写的变量名
- 不要使用
let
,而使用((...))
进行算术运算
除了处理混淆退出代码的管道的其他建议外,您还可以通过使用流程替换来避免管道,如下所示:
rsync "$OPT" "$SRCLINUX" "$TRG" &> >( tee --append "${LOGFILE}" )
它将把stdout
和stderr
(即&>
部分)重定向到一个"文件"中,该文件连接到>(...)
中进程的stdin
,在这种情况下是您想要的tee
命令。所以它很像管道,但没有管道(管道在幕后连接左边的stdout
和右边的stdin
,我们只是在这里公开了它)。
我认为状态是管道中最后一个命令的状态。
我不知道如何处理这个问题,但对于这个特定的情况,你可以重定向整个循环的输出:
while true; do
...
done | tee -a "$LOGFILE"
根据它的用途,这也可能意味着你不需要"回声日志"功能。