Lösung: Abgleichen von Verzeichnissen: updt

Hier ist die Musterlösung zu Aufgabe: Abgleichen von Verzeichnissen: updt:

#!/bin/sh
#
#####################################################################
#
# Time-stamp: "29.09.02 15:38 updt klaus@wachtler.de"
#
# Shellskript, um zwei (oder mehr) Dateien und Verzeichnisse
# abzugleichen.
#
#####################################################################
#
#           ///| |||\    || ||||    //
#          ////| |||\\   || ||||   //
#         ////|| ||||\\  || ||||  //
#        //// || |||| \\ || |||| //
#       ////==|| ||||  \\|| ||||//
#      ////   || ||||   \\| |||//
#     ////    || ||||    \| ||//
#                           |//
#         ||||    /|    //  //  ///| ||||=====//  ////=======
#         ||||   /||   //  //  ////| ||||    //  ////
#         ||||  //||  //  //  ////|| ||||   //  ////
#         |||| // || //  //  //// || ||||  //  ////
#         ||||//  ||//  //  ////==|| ||||=((  ((((=======
#         |||//   |//  //  ////   || ||||  \\  \\\\ 
#         |||/    |/  //  ////    || ||||   \\  \\\\=======
#
#####################################################################
#
# Copyright:
############
#
# (C) 1999-2002 AnyWare
#
# Dipl.Ing. Klaus Wachtler
# Breidingstr. 17
# 29614 Soltau
#
# Tel. (+49)-5191-70 2 71, (+49)-171-45 53 039
# Fax: (+49)-5191-70 2 72
# eMail AnyWare@Wachtler.de
#
#####################################################################
#
# Aufgabenstellung:
###################
#
# Dieses Skript wird mit mindestens zwei Verzeichnisnamen aufgerufen.
# Alle angegebenen Verzeichnisse werden miteinander abgeglichen, sind
# danach also identisch.
#
# Funktionsweise:
# Es wird mit cp -u ... von jedem Verzeichnis in alle anderen
# kopiert.
# Beispiel:
#    updt /home/klaus /home/klaus.archiv
# kopiert alle neueren oder fehlenden Dateien von /home/klaus nach
# /home/klaus.archiv, und dann die neueren oder fehlenden von
# /home/klaus.archiv nach /home/klaus.
# Oder:
#    updt a b c d
# kopiert entsprechend von a nach b, c, und d; dann von b nach
# a, c, d; dann von c nach a, b, d, und zuletzt von d nach a, b,
# und c.
#
# Optionen:
###########
#
# -v oder --verbose:
#      ausführlichere Ausgabe erzeugen.
#
# -h, -? oder --help:
#      es wird eine kurze Hilfe ausgegeben.
#
# -1 (eine Eins):
#      es wird nur in eine Richtung kopiert.
#      Beispiel:
#            updatedir -1 a b c d
#      kopiert von a nach b, c, und d; dann von b nach c und d, dann
#      von c nach d.
#
#####################################################################
#
# Geschichte:
#############
#
# Datum:     Name: Vers. Aenderung:
# 14. 5.1999 kw    0.0   erster Entwurf
# 17.01.2002 kw          - fehlende Verzeichnisse werden ggf. neu
#                          angelegt
#                        - existierende Dateien werden gelöscht,
#                          bevor ein Verzeichnis mit dem selben
#                          Namen angelegt wird
#                        - existierende Verzeichnisse werden
#                          gelöscht, bevor Dateien desselben Namens
#                          kopiert werden
#
#####################################################################
#
# Benoetigt:
############
#
#
#####################################################################
#
# Umgebung:
###########
#
#
#####################################################################

unset VERBOSE UNIDIRECT VERZEICHNISSE VERZEICHNISSER

#VERZEICHNISSE=""
#VERZEICHNISSER=""
#UNIDIRECT=""
#VERBOSE=""

usage()
{
            cat <<EOF
 $0 wird mit mindestens zwei Verzeichnisnamen aufgerufen.
 Alle angegebenen Dateien und Verzeichnisse werden miteinander
 abgeglichen, sind danach also identisch.

 Funktionsweise:
 Es wird mit cp -u ... von jedem Verzeichnis in alle anderen
 kopiert.
 Beispiel:
    updt /home/klaus /home/klaus.archiv
 kopiert alle neueren oder fehlenden Dateien von /home/klaus nach
 /home/klaus.archiv, und dann die neueren oder fehlenden von
 /home/klaus.archiv nach /home/klaus.
 Oder:
    updt a b c d
 kopiert entsprechend von a nach b, c, und d; dann von b nach
 a, c, d; dann von c nach a, b, d, und zuletzt von d nach a, b,
 und c.

 Optionen:
##########

 -v oder --verbose:
      ausführlichere Ausgabe erzeugen.

 -h, -? oder --help:
      es wird eine kurze Hilfe ausgegeben.

 -1 (eine Eins):
      es wird nur in eine Richtung kopiert.
      Beispiel:
            updatedir -1 a b c d
      kopiert von a nach b, c, und d; dann von b nach c und d, dann
      von c nach d.
EOF
}
# Schleife über alle Parameter, dabei jeweils eine Liste für den
# Vorwärtsdurchlauf und eine für den Rückwärtsdurchlauf
# zusammenbauen:
for arg
do
    case $arg in
        -h|-"?"|--help)
            usage
            true
            exit
            ;;
        -v|-verbose)
            VERBOSE="y"
            ;;
        -1)
            UNIDIRECT="y"
            ;;
        *)
            VERZEICHNISSE=$VERZEICHNISSE" "$arg
            VERZEICHNISSER=$arg" "$VERZEICHNISSER
            # if [ -r $arg ]
            # then
            #     VERZEICHNISSE=$VERZEICHNISSE" "$arg
            #     VERZEICHNISSER=$arg" "$VERZEICHNISSER
            # else
            #     # echo $arg" ist kein Verzeichnis!"
            #     echo $arg" ist nicht lesbar!"
            #     false
            #     exit
            # fi
            ;;
    esac
done

if [ $VERBOSE ]
then
    #echo "VERBOSE   ="$VERBOSE
    #echo "UNIDIRECT ="$UNIDIRECT
    #echo "abzugleichen: " $VERZEICHNISSE
    VERBOSE="-v"
fi

LETZTES=""
VERZEICHNISGEDREHT=""

# Vorwärtsdurchlauf durch alle Verzeichnisse/Dateien:
for d in $VERZEICHNISSE
do
    VERZEICHNISGEDREHT=$d" "$VERZEICHNISGEDREHT
    if [ $LETZTES ]
    then
        # if [ "$VERBOSE" ]
        # then
        #     echo $LETZTES" -> "$d
        # fi

        if [ ! -e $LETZTES ]
        then
            echo $LETZTES existiert nicht!
            false
            exit
        fi

        # Wenn die Quelle ein Verzeichnis ist, dann muß
        # 1) geprüft werden, ob das Ziel auch ein Verzeichnis ist.
        #    Wenn nicht, dann ggf. eine Datei mit dem Namen
        #    löschen, und ein leeres Verzeichnis anlegen.
        # 2) es muß kopiert werden in der Art:
        #      cp -... source/* dest
        #
        # Ist die Quelle kein Verzeichnis, dann muß
        # 1) das Ziel gelöscht werden, falls es ein Verzeichis ist
        # 2) es muß kopiert werden in der Art:
        #      cp -... source dest
        if [ -d $LETZTES ]
        then
            #echo Quelle $LETZTES ist ein Verzeichnis!
            if [ ! -d $d ]
            then
                #echo Ziel $d ist kein Verzeichnis!
                # Ggf. löschen:
                rm -rf $d
                # neu anlegen:
                mkdir -p $d
                # Zugriffsrechte kopieren:
                chmod --reference=$LETZTES $d
                chown --reference=$LETZTES $d
            fi
            #echo cp $VERBOSE -u -d -f -r -p $LETZTES/* $d
            cp $VERBOSE -u -d -f -r -p $LETZTES/* $d
            touch --reference=$LETZTES $d
        else
            #echo Quelle $LETZTES ist kein Verzeichnis!
            if [ -d $d ]
            then
                #echo Ziel $d ist ein Verzeichnis!
                # Ggf. löschen:
                rm -rf $d
            fi
            #echo cp $VERBOSE -u -d -f -p $LETZTES $d
            cp $VERBOSE -u -d -f -p $LETZTES $d

        fi

    fi
    LETZTES=$d
done

if [ ! "$UNIDIRECT" = "y" ]
then
    LETZTES=""
    for d in $VERZEICHNISGEDREHT
    do
        if [ $LETZTES ]
        then
            # if [ "$VERBOSE" ]
            # then
            #     echo $LETZTES" -> "$d
            # fi


            # Wenn die Quelle ein Verzeichnis ist, dann muß
            # 1) geprüft werden, ob das Ziel auch ein Verzeichnis
            #    ist.
            #    Wenn nicht, dann ggf. eine Datei mit dem Namen
            #    löschen, und ein leeres Verzeichnis anlegen.
            # 2) es muß kopiert werden in der Art:
            #      cp -... source/* dest
            #
            # Ist die Quelle kein Verzeichnis, dann muß
            # 1) das Ziel gelöscht werden, falls es ein Verzeichis
            #    ist
            # 2) es muß kopiert werden in der Art:
            #      cp -... source dest
            if [ -d $LETZTES ]
            then
                #echo Quelle $LETZTES ist ein Verzeichnis!
                if [ ! -d $d ]
                then
                    #echo  Ziel $d ist kein Verzeichnis!
                    # Ggf. löschen:
                    rm -rf $d
                    # neu anlegen:
                    mkdir -p $d
                    # Zugriffsrechte kopieren:
                    chmod --reference=$LETZTES $d
                    chown --reference=$LETZTES $d
                fi
                #echo cp $VERBOSE -u -d -f -r -p $LETZTES/* $d
                cp $VERBOSE -u -d -f -r -p $LETZTES/* $d
                touch --reference=$LETZTES $d
            else
                #echo  Quelle $LETZTES ist kein Verzeichnis!
                if [ -d $d ]
                then
                    #echo Ziel $d ist ein Verzeichnis!
                    # Ggf. löschen:
                    rm -rf $d
                fi
                #echo cp $VERBOSE -u -d -f -p $LETZTES $d
                cp $VERBOSE -u -d -f -p $LETZTES $d
            fi

        fi
        LETZTES=$d
    done
fi



AnyWare@Wachtler.de