Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/linux/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Linux Shell脚本通过文件循环,ssh进入远程服务器并在失败时继续复制文件_Linux_Bash_Shell_Ssh - Fatal编程技术网

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

Linux Shell脚本通过文件循环,ssh进入远程服务器并在失败时继续复制文件,linux,bash,shell,ssh,Linux,Bash,Shell,Ssh,给定下面的文件,我不知道如何在最内部的远程ssh命令第一次失败时,在不退出的情况下继续逐行迭代 基本前提是此脚本ssh将一个远程服务器定义为INPUT\u FILEasUSER,并将一组文件复制到远程位置进行备份。。实际备份脚本位于backup.sh中。执行哪个controller.sh 我的问题是,如果backup.sh抛出一个错误,比如对cp的权限被拒绝,而整个循环将完成,并且它将不会连接到我的INPUT\u文件中的任何reming服务器。我之所以知道这一点,是因为我特意在各种服务器上设置了

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

基本前提是此脚本ssh将一个远程服务器定义为
INPUT\u FILE
as
USER
,并将一组文件复制到远程位置进行备份。。实际备份脚本位于
backup.sh
中。执行哪个
controller.sh

我的问题是,如果backup.sh抛出一个错误,比如对
cp
的权限被拒绝,而整个
循环将完成,并且它将不会连接到我的
INPUT\u文件中的任何reming服务器。我之所以知道这一点,是因为我特意在各种服务器上设置了权限来测试这个场景

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

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

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

我在远程机器上调用了一个简单的脚本,它等待了几秒钟,然后返回了一个退出代码。您应该将一些退出代码添加到
Backup.sh
,以便检查远程命令返回的内容,然后对其执行操作

因此,在while(和
/dev/null 2>&1)中添加花括号
然后
ret=`ssh-n-t-q-o“BatchMode yes”-o“ConnectTimeout 5”-l$USER$SERVER'/home/username/timer.sh testvar;echo$?'`
echo“return:[$ret]”
如果[$ret-等式0];则
echo“成功,中止”
打破
fi
其他的
printf“${i}\t可连接到主机\n”;
fi
}

希望对您有所帮助

名称类应该是
[:lower:]
而不是
[:lower:]
这是不是
scp
对您的需要有用?scp似乎很有用,但我正在为每个服务器复制多个文件,这些文件位于不同的位置,如
/etc/fstab
/etc/oratab
和一些
/home
目录。它们备份的位置是所有服务器上的NFS共享。这样做似乎不合逻辑当我可以在每台服务器上运行shell脚本以使用
cp
并保存连接和带宽时,请使用SCP。@gorelative为什么copy2home区块会测试源目录的写入权限#codereview@gorelative在实际将数据复制到
$CPDIR/home
的三个块中发生了一些奇怪的事情-代码忽略了d不存在的目录将不可写目录视为错误,但在实际的
cp
命令执行过程中忽略任何错误。因此,
cpErrors
的命名不正确;它不会记录
cp
错误。我将备份脚本添加到问题中,并更新了代码。它仍然无法正常工作,因为它仍在中断放置。您的示例在成功时中断,无论发生什么情况,我都需要它在列表中继续。我修改了您的示例,删除了
中断
,并在
备份中。sh
我在末尾添加了一个
退出
,以强制它始终
返回0
。似乎起作用了。@gorelative哦,对不起,我想我误解了您的or最初的意图。我认为一次成功的
备份就足够了。但是很高兴你让它工作了:)
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 host\n" >> $ERRORS;
   fi
} </dev/null; done
#!/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 \n\n"
   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
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 host\n";
fi
} < /dev/null; done