Anzeige:
Ergebnis 1 bis 6 von 6

Thema: Shellscript: Backup Script mit merkwürdigen Verhalten

  1. #1
    Registrierter Benutzer
    Registriert seit
    27.10.2006
    Ort
    Marz
    Beiträge
    9

    Shellscript: Backup Script mit merkwürdigen Verhalten

    Hallo,

    ich habe mir ein kleines Backup Skript geschrieben mit dem ich zwei Verzeichnisse rekursiv auf Inhalt überprüfe. Existiert in dem Zielverzeichnis eine Datei nicht, welche aber im Quellverzeichnis existiert, wird sie im Zielverzeichnis angelegt. Das selbe gilt für Unterverzeichnisse und deren Inhalt.

    Nun zu dem Problem: Nachdem ein Unterverzeichnis gefunden wurde, wird es ggf. angelegt. Danach wird in das Verzeichnis gewechselt und alle darin befindlichen Dateien abgearbeitet. Danach wird die Funktion welche das Unterverzeichnis bearbeitet hat verlassen und die aufrufende Funktion arbeitet das aktuelle Verzeichnis weiter ab.
    Nur irgendwie steht dann plötzlich in der Variable welche sich das aktuelle Verzeichnis merkt, dass Verzeichnis vom letzten rekursiven Aufruf. Und das obwohl ich den Wert der Variable nicht ändere.
    Soll heißen: Sobald ein Unterverzeichnis abgearbeitet wurde, können alle (alphabetisch) nach dem Unterverzeichnis folgenden Dateien nicht mehr abgearbeitet werden, da das Skript meint, diese würden im bereits abgearbeiteten Unterverzeichnis liegen.

    Ich kann den Fehler einfach nicht finden und würde mich freuen wenn ihr da mal drüber schaut. Das Skript ist so ziemlich mein erstes Shell-Script und vielleicht habe ich ja einen kleinen aber entscheidenden Fehler gemacht.

    Code:
    #!/bin/sh
    
    ##########################################################
    
    function Check()
    {
      SOURCE=${1}
      BACKUP=${2}
      
      echo "Aktuelles Verzeichnis: ${SOURCE}"
      # Solange ls Ergebnis liefert
      for i in `ls ${SOURCE}`
      do
        echo "Pruefe ${SOURCE}/$i"
        # Wenn es ein Verzeichnis ist
        if [ -d "${SOURCE}/${i}" ]
        then
          # Wenn das Verzeichnis noch nicht existiert
          if [ ! -d "${BACKUP}/${i}" ]
          then
            # Lege das Verzeichnis an
            mkdir ${BACKUP}/${i}
    	echo "Verzeichnis ${BACKUP}/${i} wurde erstellt"
          fi
          # Pruefe Inhalte des Verzeichnis
          Check ${SOURCE}/${i} ${BACKUP}/${i}
        # Ansonsten ist es eine Datei
        else
          # Wenn die Datei neuer ist
          if [ "${SOURCE}/${i}" -nt "${BACKUP}/${i}" ]
          then
            # Kopiere sie
            cp ${SOURCE}/${i} ${BACKUP}/${i}
            echo "${SOURCE}/${i} wurde gesichert"
          fi
        fi
    
      done
      echo "Verzeichnis wird verlassen: ${SOURCE}"
    }
    
    ##########################################################
    
    SOURCE_DIR=${1}
    BACKUP_DIR=${2}
    
    ##########################################################
    
    if [ ! ${#} -eq 2 ]
    then
      echo "Usage: ${0} <source_dir> <backup_dir>"
      exit -1
    fi
    
    if [ ! -d ${SOURCE_DIR} ]
    then
      echo "Der erste Parameter muss ein Verzeichnis sein!"
      exit -1
    fi
    
    if [ ! -d ${BACKUP_DIR} ]
    then
      echo "Der zweite Parameter muss ein Verzeichnis sein!"
      exit -1
    fi
    
    #########################################################
    
    Check ${SOURCE_DIR} ${BACKUP_DIR}
    Vielen Dank!

  2. #2
    Registrierter Benutzer
    Registriert seit
    27.10.2006
    Ort
    Marz
    Beiträge
    9
    Ich habe jetzt eine Übergangslösung implementiert welche einfach vor dem Aufruf von Check() das aktuelle Verzeichnis (aus SOURCE und BACKUP) in einer Variable speichert und nach dem Funktionsaufruf zurück schreibt.

    Aber wieso ändert sich der Wert überhaupt erst??


    Nachtrag: Leider funktioniert diese Lösung nicht wirklich. Sobald sich in dem Unterverzeichnis ein weiteres Unterverzeichnis befindet, wird meine Lösung außer Kraft gesetzt. Das versteht ich nicht
    Geändert von bema (02-06-2007 um 23:20 Uhr)

  3. #3
    Registrierter Benutzer
    Registriert seit
    20.09.2005
    Beiträge
    61
    Hallo bema,

    ich denke, diese Zeile macht Dir die Probleme:
    Code:
     Check ${SOURCE}/${i} ${BACKUP}/${i}
    Du rufst hier die Funktion in der Funktion auf.

    Übrigens: Wenn ein Verzeichnis noch nicht existiert, könntest Du auf das Anlegen und das einzelne Kopieren der darin befindlichen Dateien verzichten, wenn Du cp -r ... benutzt.

    Viel Erfolg!
    Gruss zst

  4. #4
    Registrierter Benutzer
    Registriert seit
    27.10.2006
    Ort
    Marz
    Beiträge
    9
    Danke für den Tipp. Wenn das Verzeichnis noch nicht existiert, es einfach samt Inhalt zu kopieren ist natürlich intelligenter.

    Aber wieso darf ich in einer Funktion nicht die Funktion aufrufen? Ist das bei Shell-Scripts nicht erlaubt? Gibt es noch eine andere Möglichkeit? Sicherlich könnte ich versuchen eine iterative Lösung zu finden, aber rekursives Abarbeiten ist beim Durchlaufen von Verzeichnissen deutlich besser finde ich.

  5. #5
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Zitat Zitat von bema Beitrag anzeigen
    ...
    Aber wieso darf ich in einer Funktion nicht die Funktion aufrufen? Ist das bei Shell-Scripts nicht erlaubt? Gibt es noch eine andere Möglichkeit? Sicherlich könnte ich versuchen eine iterative Lösung zu finden, aber rekursives Abarbeiten ist beim Durchlaufen von Verzeichnissen deutlich besser finde ich.
    Doch, natürlich ist Rekursion auch in der bash möglich. Deine Idee ist also erstmal gar nicht so schlecht - ABER: Du hast ein Problem mit den Variablen SOURCE und BACKUP, das sind nämlich globale Variablen. Und da liegt der Hase im Pfeffer begraben. Nachdem der 1. rekursive Aufruf von Check in Deiner Schleife zurückkommt, sitzen die Variablen SOURCE und BACKUP auf den in der untersten Ebene zuletzt gesetzten Werten - nicht mehr auf denjenigen, die Du am Beginn der Funktion zugewiesen hast.

    Was Du suchst, ist
    Code:
    local
    . Damit deklarierst Du eine lokale Variable.

    Jan

    P.S.: Schau Dir mal rsync an - aber dann ist der ganze Spaß mit der Bash-Programmiererei hin ;-)

  6. #6
    Registrierter Benutzer
    Registriert seit
    27.10.2006
    Ort
    Marz
    Beiträge
    9
    Vielen Dank! Das war das Schlüsselwort welches mir gefehlt hat :-) Jetzt funktioniert das Skript super!

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •