sticksync - Shell Script zum Synchronisieren von USB-Disks
Funktionen von sticksync
Die Steuerdatei für sticksync - 0_sync
sticksync - Das Skript, Version 1.7
Linux Skripte ... kleine Helfer
sticksync Übersicht
Skript zur einfachen Synchronisierung von USB-Datenträgern
sticksync ist eine Weiterentwicklung meines Skripts syncstick. Wenn man viele Verzeichnisse bzw. Dateien mit syncstick aktuell halten möchte oder wenn mehrere USB-Disks bzw. USB-Sticks vorhanden sind, wird das kleine Skript sehr schnell groß und unübersichtlich.
sticksync liegt ein anderer Ansatz zugrunde. Es wird in jedem zu synchronisierenden Verzeichnis eine Datei 0_sync angelegt, in die die entsprechenden Aktionen eingetragen werden. syncstick sucht ab dem Home-Verzeichnis rekursiv durch den Verzeichnisbaum nach 0_sync Files und führt dann entsprechend dem gemounteten USB-Datenträger die definierten Aktionen durch. sticksync kann bedingt auch für Backup benutzt werden.
Funktionen von sticksync
sticksync ist ein Skript, dass die Verwendung von rsync automatisiert. sticksync sucht ab dem Home-Verzeichnis des Users durch den kompletten Verzeichnisbaum nach Steuerdateien "0_sync". Wird eine Datei namens "0_sync" gefunden, so wird sie im entsprechenden Verzeichnis verarbeitet. Das bedeutet, es wird nachgesehen, ob der entsprechende USB-Datenträger gemounted ist und dann wird rsync mit den entsprechenden Parametern aufgerufen.
Auf den ersten Blick erscheint die Arbeit 0_snyc Dateien in den unterschiedlichen Verzeichnissen anzulegen und zu pflegen etwas kompliziert. Da man aber die 0_sync Datei typischerweise pflegt, während man in diesem Verzeichnis arbeitet, z.B. im Sources Verzeichnis während der Programmierung, hält sich der Aufwand in Grenzen und die Übersichtlichkiet bleibt groß. Ich arbeite regelmäßig auf drei verschiedenen Linux-Rechnern und mir gelingt mit sticksync deren Synchronisierung problemlos.
sticksync kann reine Backups anlegen und sowohl unidirektional als auch bidirektional Verzeichnisse oder einzelne Dateien synchronisieren. Dazu gibt es die drei Anweisungen: back, copy und sync in der Steuerdatei. Zur Identifizierung der Sticks muss auf dem Stick im obersten (root) Verzeichnis eine Datei mit dem Namen des Sticks liegen. Es können mehrere Datenträger gleichzeitig gemountet sein und synchronisiert werden. Ein weiterer Vorteil ist das automatische Erkennen ob es sich um ein Linux oder VFAT Dateisystem handelt und die entsprechende Verwendung der "richtigen" rsync-Parameter.
Falls Sie Links in Ihrem Dateisystem verwenden, sollten Sie Ihren USB-Stick mit ext2 oder ext3 formatieren, damit die Links auch entsprechend sychronisiert werden können. Anderenfalls werden von rsync "Ungültige Dateien" reklamiert.
Optionen von sticksync (neu ab V 1.7)
Um das Testen und Synchronisieren einfacher zu gestalten, wurden in der Version 1.7 Kommandozeilen Parameter eingeführt. Diese sind optional und dienen hauptsächlich Testzwecken. Auch ist es manchmal wünschenswert nur einen bestimmten Ast des Dateisystems abzuarbeiten.
Der Syntax lautet: sticksync [opt] [path]
Dies ermöglicht das Prozessing eines einzelnen 0_sync Files, das mit path angegeben wird. Ist kein Pfad angegeben, so werden ab dem Home-Verzeichnis des Benutzers alle 0_sync gesucht und abgearbeitet. Wird als Path kein 0_sync File sondern ein Verzeichnis angegeben, so werden alle Unterverzeichnisse ab path durchsucht.
Mit den Optionen -d und -v können Debug-Mode und Verbose-Mode für das gesamte Prozessing eingeschaltet werden. Dies "überschreibt" die Einstellung in den einzelnen 0_sync Files.
Die Steuerdatei - 0_sync
Der Name wurde so gewählt, weil sie dann in den meisten Verzeichnissen gleich am Anfang zu finden ist. Der Name ist im Skript einstellbar.
Am einfachsten läßt sich der Aufbau der Steuerdatei anhand von Beispielen erläutern.
1: ### sync in ~/bin ### 2: #debug: 3: verbose: 4: # all pathes must have trailing / 5: 6: ### Beginn des Stick ### 7: stick:STICK2G 8: copy-r:* $STICK/backup/bin/ !--exclude *.bak 9: 10: ### Next Stick ### 11: stick:stick_emc 12: sync:sticksync $STICK/bin/ 13: sync:qi $STICK/bin/ 14: 15: ### Next Stick ### 16: stick:USB-HDD 17: backupdir:$STICK/backup/amilo/ 18: back-r:. !--exclude *~
Zeilen, die mit # beginnen, sind Kommentarzeilen. In den Zeilen 7, 11 und 16 beginnt jeweils der Abschnitt eines neuen Datenträgers. Diese Zeilen werden mit "stick:" eingeleitet. Alle Zeilen bis zum nächsten "stick:" betreffen diesen Stick. In Zeile 8 leitet "copy-r:" ein rekursives unidirektionales Kopieren von allen (=*) Dateien auf den USB-Stick ($STICK) in dessen Verzeichnis ./backup/bin/ ein, wobei die Dateien *.bak excludiert werden. Wird als Dateiname "*" angegeben um alle Dateien des Verzeichnisses zu kopieren, werden alle Dateie des Directories kopiert mit Ausnahme von 0_snyc.
Der Syntax der einzelnen Zeilen ist also:
Aktion:Source Destination [!Option(s)]
wobei es wichtig ist, Pfade (wenn es sich um Directories handelt) mit einem Slash "/" abzuschließen. Das Ausrufezeichen trennt die rsync Optionen vom Pfad ab und ist nur einmal zu verwenden. Zwischen Quelle und Ziel muss ein Leerzeichen stehen. Zwischen Ziel und dem "!" für Optionen kann das Leerzeichen entfallen.
In Zeile 12 wird die einzelne Datei "sticksync" bidirektional mit einem anderen STICK synchronisiert. Ebenso wie in Zeile 12 die Datei "qi".
In Zeile 16 wird der default Backup Pfad auf eine externe USB-HDD umgestellt. Die Backups werden dort in das Verzeichnis "amilo" abgelegt. Diese Umlenkung gilt nur für diesen Stick in diesem Verzeichnis. Mit back-r in Zeile 18 wird ein kompletter Backup inkl. Hidden-Files (Punkt Dateien) durchgeführt.
Die Angabe des Punktes als Dateinamen funktioniert auch mit copy-r und sync-r, jedoch nicht, wenn keine rekusive Option verwendet wird.
sticksync läuft normalerweise "silent" ab. Wird in 0_sync die Option "verbose:" oder "debug:" einzuschalten um die Synchronisation verfolgen zu können und/oder ggf. Fehler im Skript oder der 0_sync Datei zu finden. Im Beispiel ist "verbose" eingeschaltet und "debug" auskommentiert.
### in ~/daten/info/qi ### stick:stick_emc sync-r:*.wri $STICK/info/qi/ sync-r:*.dat $STICK/info/qi/
Aus diesem Verzeichnis werden nur die Dateien mit den Endungen "wri" und "dat" mit dem STICK "stick_emc" synchronisiert. Ich habe mir angewöhnt, den Pfad des Verzeichnisses als Kommentar in die 0_sync einzutragen. Erleichtert mir die Übersichtlichkeit, wenn ich im Editor "Geany" mehrere 0_snyc Dateien gleichzeitig offen habe.
### in ~/daten/Fotos ###
stick:HDD30G
### !!! be very carefully with --delete option
copy-r:* $STICK/bilder/!--delete --exclude *.tif
Durch die Verwendung der rsync Option "--delete" werden auf dem Zieldatenträger Dateien, die nicht im Sourceverzeichnis existieren, gelöscht. Auf der externen Festplatte wird somit eine exakte Kopie des Verzeichnisbaumes von "Fotos" gepflegt.
Die --delete Option ist nicht für Backups geeignet! Verwenden Sie die --delete Option nur wenn Sie wissen, was Sie tun.
Anweisungen von 0_sync
- stick: name ist der Beginn eines Abschnitts für einen bestimmten Datenträger
- back: führt einen Backup in das Verzeichnis das in sticksync per BACKUPDIR definiert ist durch.
- back-r: wie back: jedoch rekursiv für die entsprechenden Unterverzeichnisse.
- copy: kopiert (synchronisiert) die entsprechenden Dateien von Source nach Destination
- copy-r: wie copy: jedoch rekursiv für die entsprechenden Unterverzeichnisse.
- sync: synchronisiert die Dateien von Source nach Destination und umgekehrt.
- sync-r: wie sync: jedoch rekursiv für die entsprechenden Unterverzeichnisse.
- backupdir: In Sticksync wird das standard Backup Directory vorgegeben. Durch diese Variable in 0_sync kann es für einen einzelnen Backup temporär umgeleitet werden.
- test: schaltet den Testmodus für dieses Verzeichnis ein. Das Skript wird für dieses Verzeichnis nur testhalber durchlaufen ... es finden keine Syncvorgänge statt.
- verbose: beim Synchronisieren diese Verzeichnisses werden die einzelnen Aktionen gelistet.
- debug: dient zur Fehlersuche im Skript und/oder 0_snyc Datei. Es werden viele Informationen ausgegeben, jedoch keine Datein kopiert/synchronisiert.
Die Anweisungen "test", "verbose" und "debug" gelten nur für das Verzeichnis, in dem sie in der 0_sync freigeschaltet sind.
zum SeitenanfangDas Shell Skript sticksync
Das Skript kann einfach per copy and paste übernommen werden.#!/bin/bash ########################################################################### # Title : sticksync - backup, copy and sync files in User-HOME # Author : Bernd Holzhauer# Date : 2007-10-12 # Requires : rsync # Category : File Utilities ########################################################################### # Description # checks from user HOME recursively for 0_sync files and process them # the 0_sync should contain line starting with: # back: for backup # copy: for single way copy # sync: for dual way syncing files # Note: # - Uses different rsync parameters for VFAT and non VFAT Sticks/Disks # - The Handle filename (0_sync) may be changed to your personal taste # - Sticks should be mounted in $MOUNTDIR = /media # - $BACKDIR points to default backup BASEDIR. ########################################################################### PN=`basename "$0"` # Program name VER='1.7' ##### Variables for customising the script ##### H_FILE="0_sync" MOUNTDIR="/media" BACKUPDIR="backup" ### --- Do NOT modify/edit below --- ### Usage () { echo >&2 "$PN - Sync stuff to USB-Drive, $VER usage: $PN [opt] [path] no options required -d runs in debug mode, gives a lot of output but don't sync -h to show a short help -v switch on verbose mode during processing -? will show this message The programm searches the tree below User-Home-Dir for Job-Files named $H_FILE. Concerning to the lines in this files it backup, copy or sync files using rsync. If a path is applied, only the path and its subdirectories will be processed. Example: sticksync -d test/ will debug only the 0_sync files in home/test/ and its surdirs. " exit 1 } Help () { echo >&2 "$PN - Sync local files to USB-Drive, $VER $PN [opt] [path] - for possible options use $PN -?. The programm searches the tree below User-Home-Dir for Job-Files named $H_FILE. Concerning to the lines in this files it backup, copy or sync files using rsync. A line beginnig with '#' is treated as comment. There are 3 possible instructions: back, copy and sync. They are working just with the directory where the $H_FILE file is placed. back-r, copy-r and sync-r are doing the same but recursively thru the subdirectories, too. Job file sample 1: $H_FILE in ~/.evolution #debug: # the commands are just viewed and a lot of output is generated to # check the line ... rsync is called with option -n = dryrun # This will backup ~/.evolution tree to ~/backup/.evolution ### stick:* = always do ### stick:* ### be vary carefull with --delete option ### back-r:* !--delete Job file sample 2: $H_FILE in ~/daten/info #verbose: # enable this line will generate output while processing this dir ### The lines will be processed only if drive is mounted in /media/ # and containing a file 'stick_emc' in its root dir stick:stick_emc back:*.zkx back-r:*.html !--exclude *.20*html #one way copy instuctions copy:*.zkn \$STICK/data/ copy-r:* \$STICK/all/!--exclude *.bak # sync anweisungen sync:*.zkx \$STICK/info/ sync-r:*.html \$STICK/info/ !--exclude *.20*html ### Begin other Stick ### backupdir:\$STICK/backup/ # define (overwrite) Backup directory stick:STICK1 back-r:. # make a backup including . = hidden files ..." exit 1 } _verbose=0 _debug=0 _path="." mounted=0 while [ $# -gt 0 ] do case "$1" in -d) _debug=1; _verbose=1;; -h) Help;; -v) _verbose=1;; -?) Usage;; *) break;; # path esac shift done if [ "$1" != "" ]; then _path=$1; fi if (( $_verbose )); then echo "*** sticksync Ver. $VER: processing path=$_path ***" if (( $_debug )); then echo "+++ debug mode is on"; fi fi cd # process files in HOME dir for i in `find $_path -name $H_FILE` ; do # search for 0_sync files in HOME verbose=$_verbose debug=$_debug #if (( $debug )); then echo "*********"; fi BACKDIR=$BACKUPDIR file=$i # full file name path=${i%/*} # remove filename from path if (( $verbose )); then echo "*** found $H_FILE in $path ***"; fi dir=${path##*/} if [ "$dir" = ".Trash" ]; then echo " - skipping $file"; continue; fi # skip .Trash dir1=${path%/*} dir1=${dir1##*/} if [ "$dir1" = "$BACKDIR" ]; then echo " - skipping $file"; continue; fi # skip $BACKDIR opt_e="" while read line; do # process 0_sync file line by line if [ -z "$line" ]; then continue; fi # skip blank lines line=${line## } # strip leading blanks from line if [ "${line:0:1}" = "#" ]; then continue; fi para=${line#*!} # if no option(s) returns para = line if (( $verbose )); then echo "--> $line";fi if (( $debug )); then echo "+++ para:'$para'"; fi if [ "$para" = "$line" ]; then para="" # unset para else line=${line%!*} # strip parameter from line fi cmd=${line%:*} opt=${line#*:} opt=${opt## } # strip leading blanks src=${opt%% *} src=${src%% } # strip trailing blanks dest=${opt#* } dest=${dest%% } # strip trailing blanks if [ "$src" = "*" ] || [ "$src" = "." ]; then if [ "$cmd" != "back" ] && [ "$cmd" != "back-r" ]; then para="$para --exclude $H_FILE"; fi fi if [ "$cmd" = "test" ]; then opt_e="n"; continue; fi if [ "$cmd" = "verbose" ]; then verbose=1; opt_e="${opt_e}v"; continue; fi if [ "$cmd" = "debug" ]; then verbose=1; debug=1; opt_e="vn"; continue; fi if [ "$cmd" = "backupdir" ]; then BACKDIR=$src; continue; fi if [ "$src" = "$dest" ]; then dest=""; fi if (( $debug )); then echo "+++ cmd='$cmd' - src='$src' - dest='$dest' - para='$para' opt='$optS$opt_e'"; fi if [ "$cmd" = "stick" ]; then for _mnt in `ls /media`; do if [ -f "$MOUNTDIR/$_mnt/$src" ] || [ "$src" = "*" ]; then STICKDIR="$MOUNTDIR/$_mnt" if (( $verbose )); then if [ "$src" = "*" ]; then echo "*** Stick ALL gefunden" else echo "*** Stick $STICKDIR/$src gefunden" fi fi echo " process $path for Stick: $src" mounted=1 vfat=`mount | grep "$STICKDIR type vfat" | wc -l` #echo "vfat=$vfat - $STICKDIR type vfat" if (( vfat == 1)); then opt_s="--modify-window=1 -tu -L" opt_r="--modify-window=1 -rtu -L" else opt_s="-lptgou" opt_r="-au" fi break else mounted=0 fi done continue fi ### if no valid stick mounted - continue reading file ### if (( ! $mounted )); then continue; fi if [ "${src:1:5}" = "STICK" ]; then src=${STICKDIR}${src%\$STICK}; fi if [ "${dest:1:5}" = "STICK" ]; then dest=${STICKDIR}${dest#\$STICK}; fi if [ "${BACKDIR:1:5}" = "STICK" ]; then BACKDIR=${STICKDIR}${BACKDIR#\$STICK}; fi if (( $debug )); then echo "+++ cmd='$cmd' - path='$path'"; fi ### set/modify some values for correct processing let len=${#dest}-1 if [ $dest ] && [ "${dest:${len}:1}" != "/" ];then echo "Destination $dest '/' is missing"; exit; fi src_p=${src%/*} src_f=${src##*/} if [ "$src_p" = "src" ]; then src_p=""; fi if [ "$src_p" != "$src_f" ]; then src_p="${src_p}/"; fi if [ "${src_p:0:1}" = "*" ];then src_p=""; fi # compare first char ### BACKUP ### if [ "$cmd" = "back" ]; then cmd_back="rsync $opt_s$opt_e $para $path/$src $BACKDIR/$dir/" if (( $verbose )); then echo "--> $cmd_back"; fi $cmd_back fi if [ "$cmd" = "back-r" ]; then cmd_back="rsync $opt_r$opt_e $para $path/$src $BACKDIR/$dir/" if (( $verbose )); then echo "--> $cmd_back"; fi $cmd_back fi ### One Way Copy ### if [ "$cmd" = "copy" ]; then cmd_copy="rsync $opt_s$opt_e $para $path/$src $dest" if (( $verbose )); then echo "--> $cmd_copy"; fi $cmd_copy fi if [ "$cmd" = "copy-r" ]; then cmd_copy="rsync $opt_r$opt_e $para $path/$src $dest" if (( $verbose )); then echo "--> $cmd_copy"; fi $cmd_copy fi ### Sync both ways ### if [ "$cmd" = "sync" ]; then cmd_sync="rsync $opt_s$opt_e $para $path/$src $dest" if (( $verbose )); then echo "--> $cmd_sync"; fi $cmd_sync cmd_sync="rsync $opt_s$opt_e $para $dest/$src_f $path/$src_p" if (( $verbose )); then echo "--> $cmd_sync"; fi $cmd_sync fi if [ "$cmd" = "sync-r" ]; then cmd_sync="rsync $opt_r$opt_e $para $path/$src $dest" if (( $verbose )); then echo "--> $cmd_sync"; fi $cmd_sync cmd_sync="rsync $opt_r$opt_e $para $dest$src_f $path/$src_p" if (( $verbose )); then echo "--> $cmd_sync"; fi $cmd_sync fi done < $file if (( $verbose )); then echo "*********"; fi done cd - >/dev/null exit
Achtung: Testen Sie Ihre 0_sync Dateien vorsichtig und gründlich. Für die Sicherung Ihrer Daten und für eventuelle Datenverluste sind Sie selbst verantwortlich. Ich lehne jede Verantwortung für eventuelle Datenbeschädigungen ab.
zum SeitenanfangWarenzeichen und Marken sind Eigentum der jeweiligen Besitzer.
Das Ing.Büro Bernd Holzhauer distanziert sich grundsätzlich von gesetzeswidrigen und möglicherweise illegalen Inhalten in Seiten, auf die über www.cc-c.de verwiesen wird. Sollte Ihnen diesbezüglich etwas auffallen, melden Sie es uns bitte per email.
