#!/bin/bash #Function:自動備份給定列表中的目錄或文件,而且能夠保留N天備份的檔案。
#可備份至遠程主機指定的目錄下,但需本機能免密碼登陸到遠程主機,用到ssh-keygen
#該腳本分爲兩個文件:執行文件backup.sh和備份項目文件bakfile.lst,兩個文件必須位於同一目錄下
#Author:JianJie #Date:2016/8/26 #Usage:sudo bash backup.sh & #Version:v2 ###############################################################
logFile=/backup/local/log/`date +"%Y-%m"`.log
#日誌文件
logDir=/backup/local/log myDate=`date +"%Y-%m-%d"`
bakFileLst=bakfile.lst
#須要備份的文件或目錄放到該文件中 bakDir=/backup/local
#備份至此目錄 keepDays=5
#文件保留天數 remoteHost="rhel6.8:rhel7"
#須要備份至遠程主機的地址,注意本機需免密碼登錄到遠程主機,多個主機地址或主機名之間用‘:’分割 remoteHostDir=/backup/$HOSTNAME
#遠程主機備份目錄 currentDir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
#當前運行腳本所在的目錄
###############################################################
#判斷日誌目錄和日誌文件是否存在
if [ ! -d $logDir ];then
mkdir -p $logDir
touch $logFile else
if [ ! -e $logFile ];then
touch $logFile
fi
fi
#開始記錄日誌
echo "Backup start at $(date +"%Y-%m-%d %H:%M:%S")" >> $logFile
echo "--------------------------------------------------------" >> $logFile
echo " " >> $logFile
#判斷保存備份文件的文件列表'bakfile.lst'是否存在
if [ ! -e $currentDir/$bakFileLst ];then
echo "Error:Important file [$currentDir/$bakFileLst] has been lost,now creating..." >> $logFile
touch $currentDir/$bakFileLst
echo "The file [$currentDir/$bakFileLst] has been created,but you still need to write data in it!" >> $logFile
echo " " >> $logFile echo "--------------------------------------------------------" >> $logFile
echo "Backup end at $(date +"%Y-%m-%d %H:%M:%S")" >> $logFile
echo " " >> $logFile
exit 3
fi
paths=`cat $currentDir/$bakFileLst`
for path in $paths
do
baseName=`echo "$path" | xargs basename`
oldFile=$bakDir/$baseName.$(date --date="$keepDays days ago" +"%Y-%m-%d").txz
#判斷路徑中備份的是文件仍是目錄
#若路徑中要備份的是文件,則先進入指定路徑中的上一級
if [ -f "$path" ];then
#進入指定路徑中的上一級目錄
cd `echo "$path" | cut -d "/" -f 1-$(echo "$path"|gawk -F"/" '{print NF-1}')`
#若要備份的文件已經存在,則再也不重複備份
if [ -f $bakDir/$baseName.$myDate.txz ];then
echo "Backup file [$bakDir/$baseName.$myDate.txz] already exists!" >> $logFile
else
cp -RHpf $baseName $bakDir
cd $bakDir
#備份檔案格式爲.tar.xz,可根據須要調整,如.tar.gz或者.tar.bz2
tar -cJf $baseName.$myDate.txz $baseName
#將備份後的文件經過scp備份到遠程主機
for host in $(echo "$remoteHost" | sed 's/:/ /g')
do
scp -o ConnectTimeout=10 $baseName.$myDate.txz $host:$remoteHostDir >>$logFile 2>/dev/null && \
echo "Successful backup [$path] to the remote host:[$host:$remoteHostDir]" >>$logFile || \
echo "Backup [$path] to the remote host:[$host:$remoteHostDir] failed,please check it" >>$logFile
done
#備份完成,刪除拷貝過來的源文件
rm -rf $baseName
echo "Backup [$path] done into [$bakDir] successfuly!" >> $logFile
#若存在N天前舊文件,則刪除它
if [ -f $oldFile ];then
rm -rf $oldFile
echo "[$oldFile],delete old file successfuly!" >> $logFile
fi
fi
#路徑中備份的是目錄
elif [ -d "$path" ];then
#先判斷要備份的文件是否已經存在,若存在則再也不重複備份
if [ -f $bakDir/$baseName.$myDate.txz ];then
echo "Backup file [$bakDir/$baseName.$myDate.txz] already exists!" >> $logFile
else
cd $path
cd ..
cp -RHpf $baseName $bakDir
cd $bakDir
tar -cJf $baseName.$myDate.txz $baseName
#將備份後的文件經過scp備份到遠程主機
for host in $(echo "$remoteHost" | sed 's/:/ /g')
do
scp -o ConnectTimeout=10 $baseName.$myDate.txz $host:$remoteHostDir >>$logFile 2>/dev/null && \
echo "Successful backup [$path] to the remote host:[$host:$remoteHostDir]" >>$logFile || \
echo "Backup [$path] to the remote host:[$host:$remoteHostDir] failed,please check it" >>$logFile
done
#備份完成,刪除拷貝過來的源文件
rm -rf $baseName
echo "Backup [$path] done into [$bakDir] successfuly!" >> $logFile
#若存在N天前舊文件,則刪除它
if [ -f $oldFile ];then
rm -rf $oldFile
echo "[$oldFile],delete old file successfuly!" >> $logFile
fi
fi
else
echo "Wrong path or file:[$path],please check it" >>$logFile fi done echo " " >> $logFile echo "-------------------------------------------" >> $logFile
echo "Backup end at $(date +"%Y-%m-%d %H:%M:%S")" >> $logFile
echo " " >> $logFile
exit 0