Die Webseiten der Fachschaft Informatik am ERG Saalfeld
Verzeichnis kopieren
Für den bei uns eingesetzten Schulserver "delixs" trat in der Entwicklerliste
folgendes Problem auf: es sollte bei mehreren Schülern der Desktop neu erstellt werden.
Dazu war folgender Ansatz gewählt: von einem 'perfekt' eingerichteten Desktop als Muster
sollten alle Dateien und Verzeichnisse einschließlich Unterverzeichnisse samt Inhalt
kopiert und dabei die Eigentümer und Rechte richtig gesetzt werden. Obwohl das in meinen Augen
eine Standardaufgabe war, fand sich dazu im CPAN keine Lösung. Zwar finden sich Lösungen zum Kopieren
(auch rekursiv) und auch zum Ändern der Eigentüme (auch rekursiv), aber nicht zum korrekten Setzen der Rechte.
Hierbei sollten die Rechte für Verzeichnisse und Dateien unterschiedlich gegeben werden - Verzeichnisse
müssen ausführbar sein, Dateien sollten es hier nicht. An eine Lösung, die alle diese Forderungen auf einem
Schlag erledigt, war überhaupt nicht zu denken. Auch mit den Bordmitteln von Linux war eine (einfache)
Lösung nicht zu erstellen.
Auf eine Nachfrage in der Liste der Perl Mongers Dresden stellte mir Martin Probst eine Lösung zur Verfügung,
die rekursiv ein vorgegebenes Verzeichnis kopiert und dabei die Eigentümer ändert und die Rechte neu setzt (für
Verzeichnisse und Dateien getrennt). Dieses Script wird hier didaktisch vereinfacht und auf das rekursive Kopieren reduziert
angegeben.
Programm
use strict;
use warnings;
use File::Copy;
my $quelle = $ARGV[0];
my $ziel = $ARGV[1];
&mycopy($quelle, $ziel);
##### Ende des Hauptprogramms #####
sub mycopy {
my $src = shift; # src - source - Quelle
my $dest = shift; # dest - destination - Ziel
# wenn $src ein Verzeichnis ist
if (-d $src) {
# wir öffnen das Verzeichnis
opendir(my $dh, $src) or die "Can't open dir $src: $!"; # $dh - "Directory-Handle"
# wir lesen das Verzeichnis ein
while (my $entry = readdir($dh)) {
# wenn der Eintrag ein '.' oder '..' ist, dann weiter
if ($entry =~ m/^(\.\.|\.)$/) {
next;
};
# wenn der Eintrag ein (Unter-)Verzeichnis ist
if (-d "$src/$entry") {
# dann legen wir im Zielverzeichnis ein entsprechendes (Unter-)Verzeichnis an
mkdir "$dest/$entry";
}
# wir kopieren den Inhalt dieses Verzeichnisses
&mycopy("$src/$entry", "$dest/$entry");
}
# wir schliessen das Verzeichnis
closedir($dh);
}
# wenn $src kein Verzeichnis ist (also eine Datei)
else {
&File::Copy::copy($src, $dest);
}
}
__END__
Das Script wurde um zwei print-Anweisungen ergänzt und für eine ordentliche Ausgabe in 3 Zeilen geändert. Der Aufruf sah bei mir dann so aus:
Aufgaben
- Bringen Sie das Programm zum Laufen. Hinweis: dieses Programm liefert noch keine Ausgabe!
- Ergänzen Sie das Programm mit 2 print-Anweisungen, dass eine Ausgabe ähnlich wie in dem Screenshot erfolgt.
- Geben Sie an, wo der rekursive Aufruf erfolgt.
- Geben Sie die Abbruchbedingung an.
- Ändern Sie das Programm so ab, dass statt dem Slash als Pfadtrenner der unter Windows übliche Backslash verwendet wird (wie im Screenshot zu sehen).
- Kopieren Sie ihr Verzeichnis "Dokumente" mit diesem Programm in ein Verzeichnis auf den Desktop. Hinweis: ermitteln Sie den Namen des Verzeichnisses mit "dir"!
- Ändern Sie das Programm so ab, dass das Zielverzeichnis angelegt wird, wenn es noch nicht existiert.
zurück
© ERG Saalfeld - Hans-Dietrich Kirmse 25.05.2015
|