Shell脚本循环通过文件,ssh进入远程服务器,并在失败时继续复制文件



给定以下文件,我不知道如何在最内部的远程ssh命令第一次失败时不退出的情况下继续一行接一行地迭代。

基本前提是这个脚本ssh到一个定义为INPUT_FILEUSER的远程服务器,并将一堆文件复制到一个远程位置进行备份。。实际备份脚本在CCD_ 3中。CCD_ 4执行。

我的问题是,如果backup.sh抛出一个错误,比如cp的权限被拒绝,那么整个while循环就会结束,它将不会连接到我的INPUT_FILE中的任何剩余服务器。我之所以知道这一点,是因为我特意在各种服务器上设置了权限来测试这种情况。

我如何在文件中迭代,等待第一个ssh命令完成并强制它转到下一行而不退出。

控制器.sh

INPUT_FILE=$1
USER=$2
SCRIPT_DIR=/opt/sapdownloads/MikesUtilities/backups
BACKUP_DIR=$SCRIPT_DIR/data
DATE=`date +%m%d%y`
LOG_FILE=$SCRIPT_DIR/logs/backup.controller.log

##
# Create The Log dir and log files
##
function log(){
echo -e ${*}
echo -e "[${USER}][`date`] - ${*}" >> ${LOG_FILE}
}

#Iterate through the input file line by line
cat $INPUT_FILE | while read l;do {
#Split the line by spaces into an array
line=($l)
#make sure server is lower case
SERVER=`echo ${line[1]} | tr [:lower:] [:upper:]`
#make sure tier is uppercase
TIER=`echo ${line[0]} | tr [:upper:] [:lower:]`
log "###################################"
log "#  Tier: $TIER | SERVER: $SERVER  #"
log "###################################"
log "Making Sure we can login to the Server"
CHK=`ssh -t -q -o "BatchMode yes" -o "ConnectTimeout 5" -l $USER $SERVER "echo success"`;
if [ "success" = $CHK ] >/dev/null 2>&1
then
CPDIR=$BACKUP_DIR/$TIER/$SERVER/$DATE
log "Creating new backup directories in $CPDIR"
#make the new backup directory in $BACKUP_DIR
mkdir -p $BACKUP_DIR/$TIER/$SERVER/$DATE/etc
mkdir -p $BACKUP_DIR/$TIER/$SERVER/$DATE/home

log "Executing Remote Backup Script"
ret=`ssh -n -t -q -o "BatchMode yes" -o "ConnectTimeout 5" -l $USER $SERVER "/bin/bash $SCRIPT_DIR/backup.sh $CPDIR; echo $?"`
echo "return: [$ret]"
if [ $ret -eq 0 ]; then
echo "Success. Aborting"
break
fi
else
printf "${i}tUnable to connect to hostn" >> $ERRORS;
fi
} </dev/null; done

备份.sh

#!/bin/bash
CPDIR=$1
DATE=`date +%m%d%y`
SCRIPT_DIR=/opt/sapdownloads/MikesUtilities/backups
LOG_FILE=$SCRIPT_DIR/logs/backup.log
SIDADM_HOME=/home/${sapsid}adm
ORASID_HOME=/home/ora${sapsid}
ORACLE_HOME=/home/oracle
cpErrors=()
message=""
SENDTO="joe@example.com"
SENDFROM="team@example.com"
##
# Create The Log dir and log files
##
function log(){
#echo -e ${*}
echo -e "[${USER}][`date`] - ${*}" >> ${LOG_FILE}
}
function compileMessage(){
message="Unable to CP one or more files from the server $HOSTNAME nn"
for i in "${cpErrors[@]}"
do
message+="${i}n"
done
}
function sendMail(){
compileMessage
echo -e $message | mail -s "OS Backup Errors" -r $SENDFROM $SENDTO
}
cd /etc
#copy fstab
if [ -d "oratab" ]; then
log "Copying oratab to $CPDIR/etc"
cp oratab $CPDIR/etc
fi
#Copy fstab
if [ -d "fstab" ]; then
log "Copying fstab to $CPDIR/etc"
cp fstab $CPDIR/etc
fi
#make sure that folder exists first
if [ -d "$ORASID_HOME" ]; then
#Test to make sure we can access the folder
if [ -w "$ORASID_HOME" ]; then
log "Copying $ORASID_HOME to $CPDIR/home"
cp -rf $ORASID_HOME $CPDIR/home
else
#if we cant access that folder, send an email
log "Unable to cp $ORASID_HOME to $CPDIR/home"
cpErrors+=($ORASID_HOME)
fi
fi
#make sure that folder exists first
if [ -d "$SIDADM_HOME" ]; then
#Test to make sure we can access the folder
if [ -w "$SIDADM_HOME" ]; then
log "Copying $SIDADM_HOME to $CPDIR/home"
cp -rf $SIDADM_HOME $CPDIR/home
else
#if we cant access that folder, send an email
log "Unable to cp $SIDADM_HOME to $CPDIR/home"
cpErrors+=($SIDADM_HOME)
fi
fi
#make sure that folder exists first
if [ -d "$ORACLE_HOME" ]; then
#Test to make sure we can access the folder
if [ -w "$ORACLE_HOME" ]; then
log "Copying $ORACLE_HOME to $CPDIR/home"
cp -rf $ORACLE_HOME $CPDIR/home
else
#if we cant access that folder, send an email
log "Unable to cp $ORACLE_HOME to $CPDIR/home"
cpErrors+=($ORACLE_HOME)
fi
fi

if [ ${#cpErrors[@]} != 0 ]; then
log "Sending Email of cp errors"
sendMail
fi

正如您可能已经猜到的,ssh正在吞噬while循环中的输入,这就是它失败的原因。事实上,我不能100%确定为什么-n在这种情况下不起作用,但我们可以解决它

由于我没有你的备份脚本(也没有一般的设置),我简化了脚本,但我认为总体思路是一样的。查看服务器信息的输入文件,并尝试找到一个我们可以登录的服务器,然后看看我们是否可以在那里成功执行脚本

我在一台等待了几秒钟的远程机器上调用了一个简单的脚本,并返回了一个exit code。您应该在Backup.sh中添加一些退出代码,这样您就可以检查从远程命令返回的内容,然后对其进行操作。

因此,通过将大括号添加到while(和</dev/null)中,并从远程脚本中检索退出代码,我可以浏览列表,直到成功执行远程脚本:

cat $INPUT_FILE | while read l;do {
SERVER=($l)
CHK=`ssh -t -q -o "BatchMode yes" -o "ConnectTimeout 5" -l $USER $SERVER "echo success"`;
if [ "success" = $CHK ] >/dev/null 2>&1
then
ret=`ssh -n -t -q -o "BatchMode yes" -o "ConnectTimeout 5" -l $USER $SERVER '/home/username/timer.sh testvar;echo $?'`
echo "return: [$ret]"
if [ $ret -eq 0 ]; then
echo "Success. Aborting"
break
fi
else
printf "${i}tUnable to connect to hostn";
fi
} < /dev/null; done

希望它能帮助

最新更新