[Dresden-pm] Frage zum rekursiven Kopieren von Verzeichnissen

Hans-Dietrich Kirmse hd.kirmse at gmx.de
Di Dez 9 14:15:11 PST 2014


Hallo Martin,

danke für deine Antwort.

Am 09.12.2014 um 22:36 schrieb Martin Probst:
> Hallo Hans-Dietrich,
>
>> On 09 Dec 2014, at 07:29, Hans-Dietrich Kirmse <hd.kirmse at gmx.de> wrote:
>>
>> Guten Morgen,
>>
>> [...]
>> Leider kopiert dieses Script nur Dateien, aber keine Verzeichnisse.
>> Ich weiss zwar, dass es das Modul File::Copy::Recursive gibt, aber es müssen auch die Rechte gesetzt werden (das kann vielleicht auch noch entfallen), aber es muss auf jeden Fall der Owner geändert werden. Und wie man das mit Perl für einen Verzeichnis rekursiv macht, habe ich nicht gefunden. Auch wenn es hier vermutlich nicht gebraucht wird, bei den Rechten sollten ja eigentlich die für Dateien und Verzeichnisse unterschiedlich gesetzt werden. Auch das weiss ich nicht, wie man das machen könnte.
>>
>> Zusammengefasst: es geht um das Ersetzen des 'TODO's in dem folgenden Abschnitt:
>>
>> # wenn Datei
>> if (-f $quelldatei) {
>>   # dann kopieren (gegebenenfalls überschreiben)
>>   $okay = copy $quelldatei, $zieldatei;
>>   # wenn das Kopieren geklappt hat
>>   if ($okay) {
>>     # den Owner und Gruppe setzen
>>     chown $uid, $gid, $zieldatei;
>>     # die Rechte setzen
>>     chmod 0755, $zieldatei;
>>     # den Dateizähler um 1 erhöhen
>>     $anz_files++;
>>   }	
>> }
>> # sonst (wenn Verzeichnis)
>> else {
>>   #
>>   # TODO  (analog für Verzeichnisse, aber eben rekursiv)
>>   #
>> }		
>>
>>
>> Wäre für jeden Hinweis zu diesem Problem sehr dankbar.
>>
>> PS: da ich als Laie und Autodidakt und zudem hier "im eigenen Saft schmore" würde ich mich auch über jeden Hinweis bzw. Kritik zu diesem Script unabhängig von diesem Kopierproblem freuen.
>
> Als erster Tipp, nutze für die einzelnen Aufgaben doch sub’s. Das macht das Script an sich übersichtlicher und besser lesbar.
>
> Ich würde ähnlich wie du herangehen, also Verzeichniseinträge lesen, Test ob Verzeichnis oder Datei und dann kopieren.
> Ich würde dafür jedoch eine rekursive Funktion nutzen, die diese Aufgabe erledigt. Es sollte quasi immer, wenn die Quelle ein Verzeichnis ist, ein einlesen des Verzeichnis, Test ob Datei... usw. usf. stattfinden.

Hm, ich bin eigentlich Laie. In etwa 8 Jahren gehe ich in Rente, Perl 
habe ich mir vor ca. 10 Jahren autodidaktisch angeeignet, sicher mehr 
recht als schlecht. Da das Script für (andere) Lehrer zur Verfügung 
gestellt werden soll, die in der Schule die Server / Netze betreuen, 
meist unbezahlt und in ihrer Freizeit, wollte ich um eine stabile Lösung 
zu erstellen eigentlich auf getestete und bewährte Module zurückgreifen. 
Aber genau für diese m.E. üblichen Anforderungen habe ich kein Modul 
gefunden (kopieren alleine ist zu wenig)

> Meine Q&D Lösung sieht daher in Perl so aus:


> #!/usr/bin/perl
>
> use strict;
> use warnings;
> use File::Copy;
> use v5.10;
>
> my $src = $ARGV[0];
> my $dst = $ARGV[1];
>
> mycopy($src, $dst);
>
> sub mycopy {
>      my $s = shift;
>      my $d = shift;
>
>      if(-d $s) {
>          unless(-d "$d") {
>              warn "$d is not a directory";
>              return;
>          }
>          opendir(my $dh, $s) or die "Can't open dir $s: $!";
>          while(my $ent = readdir($dh)) {
>              next if($ent =~ m/^\.|\.\.$/);
>              if(-d "$s/$ent") {
>                  mkdir("$d/$ent");
>                  chown(1337, 42, "$d/$ent");
>                  chmod(0755, "$d/$ent");
>              }
>              mycopy("$s/$ent", "$d/$ent");
>          }
>          closedir($dh);
>      } else { # we assume that source must be a regular file
>          $d = "$d/$s" if(-d $d);
>          copy($s, $d);
>          chown(1337, 42, "$d");
>          chmod(0644, "$d");
>      }
> }

Sowas hatte ich nach der Wende mal in Pascal programmiert. für mich ist 
das nicht Q&D, sondern genau das, was ich eigentlich nicht programmieren 
wollte ;) Wie schon angegeben, habe gedacht, es gibt sowas als Modul.

> Aber mal anders gefragt, wenn du sowieso auf einem Linux-System bist, was spricht gegen ein Shell-Skript?

sehr viel: ich kann kein Shellscripting - nur ein paar Shellbefehle und 
die schlage ich erst nach ;) . Das bedeutet, ich erledige alle meine 
Aufgaben als "Hobby-Admin" bzw. bei der Mitarbeit in dem 
Schulserver-Projekt mit Perl.

Danke nochmal für diese Lösung. Ich bin damit wunschlos glücklich und 
baue das in mein Script ein. Zudem wird die Lösung ja schlanker, weil 
ich den Fall der Datei jetzt canceln kann und nur noch 2 Fälle habe für 
das rekursive kopieren des (einen) Verzeichnisses - des Desktops.

Viele Grüße
Hans-Dietrich


Mehr Informationen über die Mailingliste Dresden-pm