Bash Funktion und Logging für ein rsync-Backup-Script

 

Um mehrere Ordner über rsync zu synchronisieren, können die einzelnen Ordner für den Sync wie folgt in eine Bash-Datei geschrieben werden, soweit so einfach:

#!/bin/bash
rsync -av --delete /folder1/ /backup/folder1
rsync -av --delete /folder2/ /backup/folder2
rsync -av --delete /folder3/ /backup/folder3
rsync -av --delete /folder4/ /backup/folder4

Damit der Status des Vorganges in einer Text-Datei protokolliert werden kann, habe ich die Zeilen wie folgt angepasst:

#!/bin/bash
printf "`date '+%Y%m%d %H%M'` /folder1 `rsync -av --delete /folder1/ /backup/folder1  --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished `date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
printf "`date '+%Y%m%d %H%M'` /folder2 `rsync -av --delete /folder2/ /backup/folder2  --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished `date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
printf "`date '+%Y%m%d %H%M'` /folder3 `rsync -av --delete /folder3/ /backup/folder3  --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished `date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
printf "`date '+%Y%m%d %H%M'` /folder4 `rsync -av --delete /folder4/ /backup/folder4  --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished `date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log

Der Parameter --stats ermöglicht es, eine Zusammenfassung des Sync-Vorganges in eine Log-Datei zu schrieben;
head -n 2000 limitiert das Logfile auf 2000 Zeilen und schreibt über ">" neue Einträge an den Anfang der Log-Datei.

Damit ich die Ordnernamen in jeder Zeile nicht mehrfach tauschen muss, können diese mit Variablen ersetzt werden:

#!/bin/bash
FOLDER=/folder1
printf "`date '+%Y%m%d %H%M'` $FOLDER  `rsync -av --delete $FOLDER/ /backup$FOLDER --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished \n`date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
FOLDER=/folder2
printf "`date '+%Y%m%d %H%M'` $FOLDER  `rsync -av --delete $FOLDER/ /backup$FOLDER --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished \n`date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
FOLDER=/folder3
printf "`date '+%Y%m%d %H%M'` $FOLDER  `rsync -av --delete $FOLDER/ /backup$FOLDER --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished \n`date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log
FOLDER=/folder4
printf "`date '+%Y%m%d %H%M'` $FOLDER  `rsync -av --delete $FOLDER/ /backup$FOLDER --exclude .snapshots* --exclude .Trash* --stats | sed '0,/^$/d'` finished \n`date '+%Y%m%d %H%M'` \n\n`head -n 2000 /var/log/rsync.log`" > /var/log/rsync.log

Nachdem ich auch bei dieser Variante die Befehlszeile mehrfach kopiere, kann diese in eine Funktion ausgelagert werden. Bei dieser Gelegenheit habe ich den Einzeiler mit "\" am Ende der Zeile in mehrere Zeilen aufgeteilt:

#!/bin/bash
backup () {
	printf "`date '+%d.%m.%Y %H:%M'` | $1 \n---------------------------------------\n`\
	rsync -av --delete $1/ /backup$1 --exclude .snapshots* --exclude .Trash* --stats | \
	sed '0,/^$/d'`\nfinished: `date '+%d.%m.%Y %H:%M'` \n---------------------------------------\n\n`\
	head -n 2000 /var/log/rsync.txt`" > /var/log/rsync.txt
}
backup /folder1
backup /folder2
backup /folder3
backup /folder4

Soweit so übersichtlich, damit aber auch die Log-Ausgabe leserlicher wird, habe ich die Logzeilen in Variablen aufgeteilt. Dadurch kann zu Beginn des Logfiles gleich mal eine Zusammenfassung des Backup-Vorganges ausgegeben werden, inkl. Laufzeit der einzelnen Backup-Ordnern und dem Update der Zusammenfassung, nachdem das Script fertig ist:

#!/bin/bash
LOGFILE="/var/log/rsync.txt"
STARTTIME="`date '+%d.%m.%y %H:%M'`"
START=`date +%s`
THISLOGHEAD="______________________________________\n\
|\n\
|  Script:   $0\n\
|  Hostname: `hostname`\n\
|  Started:  $STARTTIME\n"
LOGCONTENT="`head -n 2000 $LOGFILE`"
THISLOG=""
SUMMARY=""

backup () {
	local FSTARTTIME="`date '+%H:%M'`"
	local FSTART=`date +%s`
	printf "$THISLOGHEAD|\n\n\
---------------------------------------\n\
| Summary:\n\
---------------------------------------\n\
$SUMMARY\n\
`date '+%H:%M'`-now: $1 -> $2\n\n\
---------------------------------------\n\
| Details:\
\n---------------------------------------\n\
$THISLOG\n$LOGCONTENT" > $LOGFILE
	THISLOG="$THISLOG\n`date '+%d.%m.%y %H:%M'` | $1 \n->$2\n---------------------------------------\n`\
	rsync -av --delete $1 $2 --exclude .snapshots* --exclude .Trash* --stats | \
	sed '0,/^$/d'`\nfinished: `date '+%d.%m.%y %H:%M'` \n---------------------------------------\n\n"
	printf "$THISLOGHEAD\n$THISLOG\n$LOGCONTENT" > $LOGFILE
	local FSECONDS="$((`date +%s`-$FSTART))"
	SUMMARY="$SUMMARY \n$FSTARTTIME-`date '+%H:%M'` (`date -d@$FSECONDS -u +%H:%M:%S`): $1 -> $2"
}

backup /folder1 /backup
backup /folder2 /backup
backup /folder3 /backup
backup /folder4 /backup

#Finish Script: Runtime-Information and Final-Summary:
SECONDS="$((`date +%s`-$START))"
printf "$THISLOGHEAD\
|  Finished: `date '+%d.%m.%y %H:%M'`\n\
|  Runtime:  `date -d@$SECONDS -u +%H:%M:%S`\n|\n\n\
---------------------------------------\n\
| Summary:\n\
---------------------------------------\n\
$SUMMARY\n\n\
---------------------------------------\n\
| Details:\n\
---------------------------------------\n\
$THISLOG\n\
|______________________________________\n\
$LOGCONTENT" > $LOGFILE

Die Variable $THISLOG sammelt die Log-Einträge während der Laufzeit des Scripts, $SUMMARY wird für die Zusammenfassung verwendet und mittels "printf ... > $LOGFILE" wird das Logfile bei jedem Update neu geschrieben.
Für den Header des Scripts wird die Variable $THISLOGHEAD verwendet und der ursprüngliche Log-Inhalt wird durch die Variable $LOGCONTENT angehängt. Als zweiter Parameter kann in diesem Beispiel das Ziel angegeben werden. Die Ausgabe in die Textdatei schaut mit meinen Backup-Ordnern dann ca. so aus:

______________________________________
|
|  Script:   ./rsync-backup.sh
|  Hostname: sox
|  Started:  06.08.21 09:33
|

---------------------------------------
| Summary:
---------------------------------------
 
09:33-09:33 (00:00:01): /scripts -> /media/dreambox/backup/scripts-nas 
09:33-09:41 (00:07:57): /daten/Dokumente -> /media/dreambox/backup/Dokumente 
09:41-09:42 (00:00:26): /daten/PhotoVideo -> /media/dreambox/backup/PhotoVideo 
09:42-09:47 (00:05:47): /docker -> /media/dreambox/backup/docker 
...

---------------------------------------
| Details:
---------------------------------------

06.08.21 09:33 | /scripts 
->/media/dreambox/backup/scripts-nas
---------------------------------------
Number of files: 23 (reg: 20, dir: 3)
Number of created files: 0
Number of deleted files: 0
Number of regular files transferred: 4
Total file size: 26,129 bytes
Total transferred file size: 3,347 bytes
Literal data: 3,347 bytes
Matched data: 0 bytes
File list size: 0
File list generation time: 0.001 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 4,377
Total bytes received: 109

sent 4,377 bytes  received 109 bytes  2,990.67 bytes/sec
total size is 26,129  speedup is 5.82
finished: 06.08.21 09:33 
---------------------------------------


06.08.21 09:33 | /daten/Dokumente 
->/media/dreambox/backup/Dokumente
---------------------------------------
Number of files: 353,503 (reg: 324,561, dir: 28,891, link: 51)
Number of created files: 1 (reg: 1)
Number of deleted files: 0
Number of regular files transferred: 83
Total file size: 204,805,207,475 bytes
Total transferred file size: 449,566,337 bytes
Literal data: 449,566,337 bytes
Matched data: 0 bytes
File list size: 3,143,254
File list generation time: 0.038 seconds
File list transfer time: 0.000 seconds
Total bytes sent: 459,277,206
Total bytes received: 31,776

sent 459,277,206 bytes  received 31,776 bytes  961,903.63 bytes/sec
total size is 204,805,207,475  speedup is 445.90
finished: 06.08.21 09:41 
---------------------------------------

...
positive Bewertung({{pro_count}})
Beitrag bewerten:
{{percentage}} % positiv
negative Bewertung({{con_count}})

DANKE für deine Bewertung!

Fragen / Kommentare