![]() |
HowTo.BackupScript HistoryHide minor edits - Show changes to markup June 10, 2008, at 01:02 PM
by --
Added line 1:
[@ Added line 432:
@] June 10, 2008, at 01:02 PM
by --
Added lines 1-430:
ROOT_UID=0; OK=0; KO=1;
BACKUP_DIRECTORY="/backup"; BACKUP_DIRECTORY_PATTERN="Backup"; BACKUP_PARTITION="/dev/sdb2"; STANDARD_CONFIG_FILE="/etc/backup"
G_BackupDirectory="Not yet assigned"; G_DatedBackupDirectory="Not yet assigned"; G_Date="Not yet assigned"; G_NbrFilesAlreadyExist=0; G_NbrDirAlreadyExist=0;
function _Report { CurrentTime?=`/bin/date | /usr/bin/awk '{print $4}'`;
/bin/echo "$G_Date $CurrentTime $1 : $2";
}
function _ReportDiskSpace { Message="$BACKUP_PARTITION full by ";
Message=$Message"`/bin/df | grep $BACKUP_PARTITION | /usr/bin/awk '{print $5}'`";
Message=$Message" (available=";
Message=$Message"`/bin/df | grep $BACKUP_PARTITION | /usr/bin/awk '{print $4}'`";
Message=$Message" - used =";
Message=$Message"`/bin/df | grep $BACKUP_PARTITION | /usr/bin/awk '{print $3}'`";
Message=$Message")";
_Report "INFO" "$Message" ;
}
function _IsRootUser { if [ `/usr/bin/id -u` -ne $ROOT_UID ]; then
{
return $KO;
}
else
{
return $OK;
}
fi;
}
function _UpdateDateGlobalVariables { # G_Date
# ======
# Year
G_Date=`/bin/date | /usr/bin/awk '{print $6}'`;
# Month
case "`/bin/date | /usr/bin/awk '{print $2}'`" in
"Jan") G_Date="$G_Date"01;;
"Feb") G_Date="$G_Date"02;;
"Mar") G_Date="$G_Date"03;;
"Apr") G_Date="$G_Date"04;;
"May") G_Date="$G_Date"05;;
"Jun") G_Date="$G_Date"06;;
"Jul") G_Date="$G_Date"07;;
"Aug") G_Date="$G_Date"08;;
"Sep") G_Date="$G_Date"09;;
"Oct") G_Date="$G_Date"10;;
"Nov") G_Date="$G_Date"11;;
"Dec") G_Date="$G_Date"12;;
*) _Report "ERROR" "Improper value";
exit;;
esac
# Day
DayNumber?=`/bin/date | /usr/bin/awk '{print $3}'`;
if [ $DayNumber -lt 10 ]; then
{
G_Date="$G_Date"0"$DayNumber";
}
else
{
G_Date="$G_Date$DayNumber";
}
fi;
}
function _UpdateDestinationDirectoriesGlobalVariables { if [ -z "$1" ]; then
{
_Report "ERROR" "The backup keyword is empty";
exit $KO;
}
else
{
G_BackupDirectory="$BACKUP_DIRECTORY/$BACKUP_DIRECTORY_PATTERN$1";
G_DatedBackupDirectory="$BACKUP_DIRECTORY/$BACKUP_DIRECTORY_PATTERN$1$G_Date";
}
fi;
}
function _RecursiveHardLink { if [ ! -e $1 ]; then
{
_Report "WARNING" "Source directory $1 does not exist"; # can happen if run for the very first time
return $KO;
}
elif [ -f $1 ]; then
{
_Report "ERROR" "Source directory $1 is a file";
exit $KO;
}
fi;
if [ -e "$2" ]; then
{
if [ -d "$2" ]; then
{
let "G_NbrDirAlreadyExist=$G_NbrDirAlreadyExist+1";
}
else
{
_Report "ERROR" "$2 already exists and is a file";
exit $KO;
}
fi;
}
else
{
/bin/mkdir "$2";
}
fi;
IFS=$'\n';
for inode in $(ls $1); do
if [ -f "$1/$inode" ]; then
{
if [ -e "$2/$inode" ]; then
{
if [ -d "$2/$inode" ]; then
{
_Report "ERROR" "$2/$inode already exists and is a directory";
exit $KO;
}
else
{
let "G_NbrFilesAlreadyExist=$G_NbrFilesAlreadyExist+1";
}
fi;
}
else
{
/bin/ln "$1/$inode" "$2/$inode";
}
fi;
}
elif [ -d "$1/$inode" ]; then
{
_RecursiveHardLink "$1/$inode" "$2/$inode";
}
fi;
done
}
function _Backup { # test parameters
# ---------------
if [ ! -e "$1" ]; then
{
_Report "ERROR" "The source directory to backup $1 does not exist";
exit $KO;
}
elif [ -f "$1" ]; then
{
_Report "ERROR" "The source directory to backup $1 is a file";
exit $KO;
}
fi;
if [ ! -e "$2" ]; then
{
_Report "WARNING" "The backup directory $2 does not exist";
/bin/mkdir "$2";
_Report "INFO" "Directory $2 created";
}
elif [ -f "$2" ]; then
{
_Report "ERROR" "The backup directory $2 is a file";
exit $KO;
}
fi;
# rsync the directories
# ---------------------
/usr/bin/rsync -v -a --delete $1/ $2/
}
function _DeleteDatedBackups { # compute the directories filter for ls # ===================================== let Lgth=`expr length $G_DatedBackupDirectory`-8; Filter="`expr substr $G_DatedBackupDirectory 1 $Lgth`*"; # delete all files except NbrFiles? # ================================ IFS=$'\n'; let FilesNbr?=`ls -d $Filter | wc -l`-1; let FilesToRemove?=`ls -d $Filter | wc -l`-$1; _Report "INFO" "Found $FilesNbr directories for $1 allowed" if [ $FilesToRemove -gt 0 ]; then { _Report "INFO" "Will remove $FilesToRemove directories" FilesList?="`ls -d $Filter | tail -$FilesNbr | head -$FilesToRemove`"; for File in $FilesList; do _Report "INFO" "Removing $File..."; rm -r $File; done } fi; }
function _BackupADirectory { # check parameters
# ================
if [ ! -e "$1" ]; then
{
_Report "ERROR" "The source directory to backup $1 does not exist";
exit $KO;
}
elif [ -f "$1" ]; then
{
_Report "ERROR" "The source directory to backup $1 is a file";
exit $KO;
}
fi;
if [ -z "$2" ]; then
{
_Report "ERROR" "The backup keyword is empty";
exit $KO;
}
fi;
if [ -z "$3" ]; then
{
_Report "ERROR" "No backup length parameter";
exit $KO;
}
elif [ $3 -lt 0 ]; then
{
_Report "ERROR" "The backup length ($3) must be positive or nul";
exit $KO;
}
fi;
# Update directories name global variables
# ========================================
_UpdateDestinationDirectoriesGlobalVariables $2;
_Report "INFO" "The source to backup is $1";
_ReportDiskSpace;
# delete the unnecessary dated backups
# ====================================
_DeleteDatedBackups $3
# Hard links creation
# ===================
if [ $3 -gt 0 ]; then
{
_Report "INFO" "The dated backup directory is $G_DatedBackupDirectory";
_Report "INFO" "Dated backup in progress...";
G_NbrFilesAlreadyExist=0;
G_NbrDirAlreadyExist=0;
_RecursiveHardLink $G_BackupDirectory $G_DatedBackupDirectory;
if [ $G_NbrFilesAlreadyExist -gt 0 -o $G_NbrDirAlreadyExist -gt 0 ]; then
{
_Report "WARNING" "$G_NbrFilesAlreadyExist files and $G_NbrDirAlreadyExist directories were already existing : those files have not been overwritten";
}
fi;
_Report "INFO" "Dated backup completed...";
_ReportDiskSpace;
}
else
{
_Report "INFO" "No dated backup as requested"
}
fi;
# start the backup
# ================
_Report "INFO" "The current backup directory is $G_BackupDirectory";
_Report "INFO" "Backup in progress...";
_Backup $1 $G_BackupDirectory;
_Report "INFO" "Backup completed...";
_ReportDiskSpace;
}
function _ScheduleBackupsFromFile { # test if the file exists
# -----------------------
if [ ! -e $1 ]; then
{
_Report "ERROR" "The config file $1 does not exist";
exit $KO;
}
elif [ ! -f $1 ]; then
{
_Report "ERROR" "$1 is not a file";
exit $KO;
}
fi;
# read the file and run the backup
# --------------------------------
IFS=" "; # tab
cat $1 | while read SourceDir? Keyword MaxDatedBackups?; do
_BackupADirectory $SourceDir $Keyword $MaxDatedBackups;
IFS=" "; # tab, overwritten by _RecursiveHardLinks
done
}
function _DisplaySyntax { _Report "" "Syntax : $0"; _Report "" "1 argument -> use this argument as a config file"; _Report "" "3 arguments -> source directory to backup"; _Report "" " -> backup keyword"; _Report "" " -> backup length (can be 0 or more)"; }
_UpdateDateGlobalVariables;
if ( ! _IsRootUser ); then { _Report "ERROR" "Must be root to use the script"; exit; } fi;
case $# in 1) _ScheduleBackupsFromFile $1;; 3) _BackupADirectory $1 $2 $3;;
esac |