Allerdings fände ich es grundsätzlich interssant, den Code zu sehen.
Das Skript ist eigentlich nur für mich, also nicht in jedem Punkt "schön" und sehr speziell auf meine Anforderungen zugeschnitten. Ich traue mir allerdings zu, es binnen Minuten an andere Anforderungen (auch Speicherung der Daten von oder auf einen anderen "Server") anzupassen:
#!/bin/bash
## Konfiguration:
sourceDir='/'; #Source
backupDir='/data/backup'; #Target
backupExludesFile='/root/bin/backup.exludes';
backupName='nightly';
maxOldBackups=28;
## Programm:
YMD="$(date +%F)";
backupDateName="${YMD}-${backupName}";
backupRegex="^2[0-9]{3}-[0-9]{2}-[0-9]{2}-${backupName}$";
backupLogFile="${YMD}-${backupName}.log";
backupErrorLogFile="${YMD}-${backupName}.err.log";
if [ -d "${backupDir}" ]; then
oldDir=$(pwd);
cd ${backupDir};
date > "${backupLogFile}";
if [ -f "${backupLogFile}" ]; then
date > "${backupErrorLogFile}";
### Löschen der alten Backups:
countBackups=$(ls -d * | grep -P "${backupRegex}" | wc -l);
if [ ${countBackups} -gt ${maxOldBackups} ]; then
let newcounter=0;
for dir in $(ls -d * | grep -P "${backupRegex}" | sort); do
newCounter=$(($newCounter+1));
rest=$((${countBackups}-${maxOldBackups}));
if [ ${newCounter} -le ${rest} ]; then
rm -rf "${dir}" 2>> "${backupErrorLogFile}" &&
echo "Backup gelöscht: ${dir}" >> "${backupLogFile}";
oldDate=$(echo "${dir}" | cut -d '-' -f 1,2,3);
oldBackupLogFile="${oldDate}-${backupName}.log";
rm "${oldBackupLogFile}" &&
echo "altes Logfile gelöscht: ${oldBackupLogFile}" >> "${backupLogFile}";
oldBackupLogFile="${oldDate}-${backupName}.err.log";
rm "${oldBackupLogFile}" &&
echo "altes Error-Logfile gelöscht: ${oldBackupLogFile}" >> "${backupLogFile}";
fi
done
fi
### Finden des letzten Backups:
lastBackup="$(ls -d * | grep -P "${backupRegex}" | sort | tail -n1)";
if [ "${lastBackup}" = "${backupDateName}" ]; then
lastBackup="";
fi
### Anlegen des neuen Backups:
if [ -z ${lastBackup} ]; then
rsync -avu --exclude-from "${backupExludesFile}" "${sourceDir}" "${backupDir}/${backupDateName}" >> "${backupLogFile}" 2>> "${backupErrorLogFile}";
else
rsync -avuH --link-dest="${backupDir}/${lastBackup}" --exclude-from "${backupExludesFile}" "${sourceDir}" "${backupDir}/${backupDateName}" >> "${backupLogFile}" 2>> "${backupErrorLogFile}";
fi
cd "${oldDir}";
else
logger -t "nightly-backup" "Fatal: Backup-Dir ${backupDir} kann nicht beschrieben werden.";
echo "Fatal: Backup-Dir ${backupDir} kann nicht beschrieben werden." | mail -s "Backupfehler" root;
fi
else
logger -t "nightly-backup" "Fatal: Backup-Dir ${backupDir} nicht verfügbar!";
echo "Fatal: Backup-Dir ${backupDir} nicht verfügbar!" | mail -s "Backupfehler" root;
fi
Die excludes-Datei:
/data/*
/dev/*
/sys/*
/proc/*
/media/*
/mnt/*
/tmp/*
/run/*
/var/run/*
/var/swap
/var/cache/*
/var/tmp/*