SELFHTML/Navigationshilfen CGI/Perl Perl-Funktionen |
Funktionen für Datei- und Verzeichnismanagement |
|
Allgemeines zu diesen Funktionen |
|
Perl kommt aus der Unix-Welt, und aus diesem Grund sind die Funktionen rund um Datei- und Verzeichnis-Management auch an den typischen Möglichkeiten von Unix orientiert. Einige dieser Funktionen sind nur anwendbar, wenn das Perl-Script auf einem Unix-System ausgeführt wird. Funktionen, die sich auf andere Betriebssysteme übertragen lassen, funktionieren auch dort. Bei den Beschreibungen zu den einzelnen Funktionen wird darauf hingewiesen, wenn es Beschränkungen auf bestimmte Betriebssystem-Typen gibt.
Weitere Funktionen zur Dateiverwaltung, etwa zum Kopieren und Verschieben von Dateien, gibt es ebenfalls, doch gehören sie nicht zum Kernel von Perl. Solche Funktionen sind über das Standardmodul FILE
erreichbar.
Die hier beschriebenen Funktionen erwarten als Parameter Pfadangaben. Als Trennzeichen zwischen Verzeichnisnamen bei Pfadangaben benutzen Sie aus Portabilitätsgründen am besten immer den einfachen Schrägstrich, auch bei Perl-Scripts, die unter MS Windows laufen sollen. Perl unter MS Windows setzt dies intern in die Microsoft-eigene Backslashes um. Beispiele:
|
Relative Pfadangaben sollten Sie nur verwenden, wenn das aktuelle Arbeitsverzeichnis bekannt ist.
Um das aktuelle Arbeitsverzeichnis in Perl zu ermitteln, können Sie notieren:
use Cwd; my $Arbeitsverzeichnis = cwd; |
In dem Skalar $Arbeitsverzeichnis
steht dann anschließend der vollständige Pfad zum aktuellen Arbeitsverzeichnis. Benutzt wird dazu das Standardmodul cwd
.
Viele der hier beschriebenen Funktionen erwarten als Parameter eine Rechteangabe.
Bei Unix-Systemen haben alle Einträge eines Dateisystems Rechte. Jede Datei, jedes Verzeichnis gehört einem Benutzer, und jeder Benutzer gehört zu einer Benutzergruppe. Der so genannte Superuser, der Benutzer mit der so genannten root-Kennung, kann Benutzer und Benutzergruppen einrichten und Logindaten für die einzelnen Benutzer des Systems vergeben.
Ein Benutzer, der sich an einem Unix-System einloggt, erhält vom Betriebssystem eine individuelle Benutzerkennung, die User-ID (UID). Ebenso erhält jede Benutzergruppe eine Gruppen-ID (GID). Beide IDs sind Nummern. In einigen der hier beschriebenen Funktionen spielen diese IDs eine Rolle. Solche Funktionen sind dann in der Regel nur anwendbar, wenn das Perl-Script in einer Unix-Umgebung laufen soll.
Das System weiß stets, welcher eingeloggte Benutzer eine Datei oder ein Verzeichnis erzeugt. Die Datei bzw. das Verzeichnis gehört dann diesem Benutzer und seiner primären Benutzergruppe. Zusätzlich dazu ist es auf Unix-Systemen aber auch möglich, für jede Datei oder jedes Verzeichnis die Zugriffsrechte für besitzenden Benutzer, seine primäre Benutzergruppe und für Fremdbenutzer ("Rest der Welt") festzulegen. Dabei wird unterschieden zwischen Leserecht, Schreibrecht und Ausführungsrecht. Jedes dieser drei Rechte (Lesen, Schreiben, Ausführen) kann für jede der drei Benutzertypen (Besitzer, zugehörige Gruppe und Rest der Welt) auf "ja" oder "nein" gesetzt werden. Die Darstellung dieser Rechte erfogt üblicherweise in zwei Arten: entweder als eine Zeichenkette von 3 mal 3, also 9 Zeichen, oder als Oktalzahl mit 3 Ziffern.
Darstellung als Zeichenkette (Beispiele):
rwxrwxrwx rw-r--r-- rwx------ |
Der Buchstabe r
steht für Lesen (read), w
für Schreiben (write), und x
für Ausführen (execute). Ist ein Buchstabe gesetzt, ist damit das entsprechende Recht gesetzt. Ist das entsprechende Recht nicht gesetzt, ist stattdessen ein Bindestrich -
notiert. Die ersten drei der neun Zeichen bedeuten die Lese-, Schreib- und Ausführungsrechte des besitzenden Benutzers der Datei, die zweiten drei Zeichen die Lese-, Schreib- und Ausführungsrechte seiner Gruppe, und die dritten drei Zeichen die Lese-, Schreib- und Ausführungsrechte für den "Rest der Welt".
Der Wert rwxrwxrwx
bedeutet: alle drei Benutzertypen (besitzender Benutzer, zugehörige Gruppe und Rest der Welt) haben an der Datei alle drei Rechte.
Der Wert rw-r--r--
bedeutet: der besitzende Benutzer hat die Rechte "Lesen" und "Schreiben", aber nicht "Ausführen", seine Gruppe und der Rest der Welt haben nur das Recht "Lesen", aber nicht die Rechte "Schreiben" und "Ausführen".
Der Wert rwx------
bedeutet: der besitzende Benutzer hat alle Rechte, seine Gruppe und der Rest der Welt haben überhaupt keine Rechte.
Darstellung als Oktalzahl (gleiche Beispiele wie zuvor):
0777 0644 0700 |
Bei dieser Darstellung, die von den meisten der hier beschriebenen Funktionen gefordert wird, wird eine Zahl mit einer führenden 0 notiert, was Perl die Zahl als Oktalzahl interpretieren lässt. Die Zahl selber besteht aus den 3 nachfolgenden Ziffern. Bei Oktalzahlen sind nur Ziffern zwischen 0 und 7 erlaubt. Die erste Ziffer steht für die Rechte des besitzenden Benutzers, die zweite Ziffer für die seiner Benutzergruppe, und die dritte für die vom "Rest der Welt". Das Recht "Lesen" gibt 4 "Punkte", das Recht "Schreiben" 2 Punkte, und das Recht "Ausführen" 1 Punkt. Durch Zusammenzählen der Punkte ergibt sich das jeweilige Recht.
Der Wert 0777
bedeutet: alle drei Benutzertypen (besitzender Benutzer, zugehörige Gruppe und Rest der Welt) haben an der Datei alle drei Rechte (4+2+1).
Der Wert 0644
bedeutet: der besitzende Benutzer hat die Rechte "Lesen" und "Schreiben" (4+2), seine Gruppe und der Rest der Welt haben nur das Recht "Lesen" (4).
Der Wert 0700
bedeutet: der besitzende Benutzer hat alle Rechte, seine Gruppe und der Rest der Welt haben überhaupt keine Rechte.
Als Hilfe für Dateirechte können Sie auch den Unix-Dateirechte-Setzer (chmod) benutzen.
Die einfachste und schnellste Methode, um gezielt auf bestimmte Eigenschaften einer Datei oder eines Verzeichnisses zuzugreifen, ist diejenige, die Perl mit den Dateitestoperatoren zur Verfügung stellt. Einige der Dateitestoperatoren geben eine Zahl zurück, beispielsweise die Größe einer Datei in Bytes, andere nur, ob eine Aussage zutrifft oder nicht. Die Übersicht der Dateioperatoren finden Sie in der Tabelle der Dateitestoperatoren.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Textdatei = "/usr/bin/myprog/readme.txt"; my $UnbekannteDatei = "/usr/bin/myprog/doit"; my $Perldatei = "/usr/webcgi-local/betrag.pl"; my $Logdatei = "/usr/web/logs/heute.log"; print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><body>\n"; print "Die Textdatei hat eine Größe von ",-s $Textdatei," Bytes<br>\n"; printf "Die Textdatei wurde vor %.3f Tagen zuletzt bearbeitet<br>\n",-M $Textdatei; print "Die unbekannte Datei ist ",-d $UnbekannteDatei ? "ein Verzeichnis<br>\n" : "kein Verzeichnis<br>\n"; print "Die Perldatei ",-e $Perldatei ? "existiert<br>\n" : "existiert nicht<br>\n"; print "Es hat Zugriffe gegeben" if not -z $Logdatei; print "</body></html>\n"; |
Alle Dateitestoperatoren zum Abfragen von Eigenschaften bestehen aus einem Minuszeichen, gefolgt von einem Buchstaben ohne Leerzeichen dazwischen. Dahinter folgt, durch ein Leerzeichen getrennt, die Angabe der gewünschten Datei, wenn erforderlich mit vollständigem Pfadnamen.
Im obigen Beispiel 1 werden drei Skalare definiert, die Dateinamen mit Pfadangaben speichern. Anschließend wird HTML-Code an den den Browser gesendet. Dabei werden verschiedene Aussagen über Eigenschaften der drei Dateien getroffen.
Die erste print
-Anweisungen enthält als ein Parameter einen Dateitestoperator (siehe dazu auch die Syntax von print). In der Anweisung wird durch Anwendung von -s $Textdatei
die Größe der Datei ermittelt und an der entsprechenden Stelle ausgegeben.
Im zweiten Befehl, einem Aufruf von printf, wird mit -M $Textdatei
ermittelt, seit wie viel Tagen die Datei nicht mehr geändert wurde. Auch dieser Wert wird ausgegeben. Da -M
eine Gleitkommazahl zurückgibt, wird die Ausgabe mit Hilfe der printf
-Funktion auf drei Nachkommastellen gekürzt.
In den nachfolgenden beiden print
-Befehlen sehen Sie eine typische Konstruktion, wie Dateitestoperatoren, die nur "wahr" oder "falsch" zurückgeben, angewendet werden. Zum Einsatz kommt in beiden Fällen eine einfache Entweder-Oder-Abfrage. Im ersten Fall wird mit dem Dateitestoperator -d
abgefragt, ob die unbekannte Datei ohne Endung ein Verzeichnis ist oder eine normale Datei. Im zweiten Fall wird mit -e
abgefragt, ob die Perldatei existiert oder nicht.
Das letzte Beispiel zeigt, wie ein Dateitestoperator in eine nachgestellte bedingte Anweisung eingebaut wird - ebenfalls eine typische Konstruktion. Das Beispiel ermittelt mit Hilfe des Dateitestoperators -z
, ob die Datei leer ist oder nicht. Wenn sie nicht leer ist, wird eine Meldung ausgegeben, daß es Zugriffe gegeben hat.
Dateitestoperatoren können auch vergebene Datei-Handle anstelle von direkten Dateiangaben verarbeiten. Wenn Sie beispielsweise mit open(FILE,"<datei.htm")
eine Datei zum Lesen öffnen, können Sie mit -s FILE
die Größe der Datei ermitteln.
|
Macht ein Verzeichnis zum aktuellen Arbeitsverzeichnis. So ist es möglich, nach dem Wechseln in ein Verzeichnis dort abgelegte Dateien zu öffnen, ohne sich um Pfadnamen zu kümmern.
Erwartet als Parameter:
1. den Pfadnamen des Verzeichnisses, zu dem gewechselt werden soll. Es kann sich um eine relative oder eine absolute Pfadangabe handeln.
Es ist auch möglich, keinen Parameter zu übergeben. In diesem Fall wechselt die Funktion in das Verzeichnis, das in der Umgebungsvariablen HOME gespeichert ist.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); chdir("/usr/txt/rfc"); open(DATEI,"<rfc1867.txt"); my @Zeilen = <DATEI>; close(DATEI); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body><pre>\n"; print "@Zeilen"; print "</pre></body></html>\n"; |
Das Beispiel-Script wechselt mit chdir
in das Verzeichnis /usr/local/txt/rfc
, also in ein bestimmtes Unterverzeichnis ab Wurzelverzeichnis gerechnet. Dort wird dann eine Datei geöffnet, eingelesen und wieder geschlossen (Erläuterungen zu diesen Befehlen siehe open). Anschließend wird HTML-Code an den Browser gesendet. Dabei werden die Zeilen der eingelesenen Datei ausgegeben.
Setzt die Rechte zum Lesen, Schreiben und Ausführen einer oder mehrerer Dateien für Benutzer, Benutzergruppe und Rest der Welt (Unix-spezifisch).
Erwartet als Parameter:
1. eine Rechteangabe. Der Wert muss numerisch oktal übergeben werden, nicht als Zeichenkette!
2. bis n. eine oder mehrere Dateien/Verzeichnisse, für die diese Rechte gesetzt werden sollen, wenn nötig mit Pfadnamen.
Gibt die Anzahl der vorgenommenen Änderungen zurück.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Verzeichnis = "/usr/web/docs/cgi-bin"; chdir($Verzeichnis); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; my @Dateien = glob("*.pl"); my $Datei; foreach $Datei (@Dateien) { chmod(0755,$Datei); print "$Datei auf 0755 gesetzt<br>\n"; } print "</body></html>\n"; |
Das Beispiel setzt alle Perldateien eines CGI-Verzeichnisses auf die Rechte 0755
- auf vielen Servern eine sinnvolle Einstellung für CGI-Scripts. Zu diesem Zweck werden alle Dateien des Verzeichnisses $Verzeichnis
(dem CGI-Verzeichnis) mit glob ausgewählt. Die Liste @Dateien
, in der die ausgewählten Dateien anschließend stehen, wird daraufhin in einer foreach-Schleife abgearbeitet. Mit chmod(0755,$Datei)
wird die jeweils aktuelle Perldatei mit den gewünschten Rechten versehen. Zur Kontrolle gibt das Beispiel-Script aus, welche Dateien geändert wurden.
Jede Datei unter Unix hat einen Eigentümer, der durch zwei Zahlen identifiziert wird: die persönliche User-ID (UID) und die zugehörige Gruppen-ID (GID). Die Funktion andert Besitzer und Besitzergruppe von einer oder mehreren Dateien. Auf den meisten Unix-Systemen ist dazu eine Root-Kennung erforderlich.
Erwartet als Parameter:
1. die numerische UID (User-ID des Besitzers),
2. die numerische GID (Gruppen-ID der Besitzergruppe),
3. bis n. eine oder mehrere Dateien, für die angegebenen UID und GID gelten sollen, wenn nötig mit Pfadnamen.
Gibt die Anzahl der vorgenommenen Änderungen zurück.
#!/usr/bin/perl -w use strict; chdir("/usr/data/web/htdocs"); opendir(DIR, "/usr/data/web/htdocs") || die "$!\n"; my @Eintraege = readdir(DIR); closedir(DIR); foreach (@Eintraege) { chown(1034, 518, $_) if -f $_; } |
Das Beispiel ändert für alle regulären Dateien des angenommenen Verzeichnisses /usr/data/web/htdocs
die Besitzerschaft auf den Benutzer mit der User-Id 1034 und der Gruppen-Id 518.
Bestimmt ein neues Verzeichnis als "virtuelles" Wurzelverzeichnis. Absolute Pfadangaben, die mit /
beginnen, beziehen sich anschließend darauf. Auf den meisten Unix-Systemen ist zum Anwenden dieser Funktion eine Root-Kennung erforderlich.
Erwartet als Parameter:
1. den Pfadnamen des Verzeichnisses, das zum Wurzelverzeichnis werden soll. Es kann sich um eine relative oder eine absolute Pfadangabe handeln.
Es ist auch möglich, keinen Parameter zu übergeben. In diesem Fall wird der Inhalt der vordefinierten Variablen $_
als Pfadnamen des gewünschten Verzeichnisses interpretiert.
#!/usr/bin/perl -w use strict; chroot("/usr/local/web/domains/eidideldum"); chdir("/"); opendir(DIR, "."); my @Eintraege = readdir(DIR); closedir(DIR); foreach(@Eintraege) { print "$_\n"; } |
Das Beispiel setzt den Pfad /usr/local/web/domains/eidideldum
als neues Wurzelverzeichnis. Anschließend wechselt das Script mit chdir in das neue Wurzelverzeichnis ("/")
. Zur Kontrolle liest das Script das aktuelle Verzeichnis (".")
ein und listet die eingelesenen Verzeichniseinträge anschließend auf (Erläuterungen zu diesen Befehlen siehe opendir).
Wählt aus einem Verzeichnis alle Dateien aus, die einem bestimmten Dateinamenmuster entsprechen. Das ist wesentlich einfacher als das Operieren mit den Funktionen opendir, readdir und closedir. Der Nachteil von glob
ist allerdings, daß diese Funktion eine Unix-Shell startet, um an ihr Ergebnis zu kommen. Die Funktion ist daher nur auf Unix-Systemen verfügbar, und ausführbar ist sie auch nur, wenn das Script ausreichende Rechte zum Starten der Shell besitzt. Es gibt jedoch bei den Standardmodulen für Dateiverwaltung ein Modul, das den glob
-Algorithmus komplett in Perl ausführt.
Erwartet als Parameter:
1. Das Dateinamenmuster, wenn nötig mit Pfadangabe.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my @HTML_Dateien = glob("/usr/web/docroot/*.htm"); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; foreach (@HTML_Dateien) { print "$_<br>\n"; } print "</body></html>\n"; |
Das Beispielscript wählt im Verzeichnis /usr/web/docroot
alle Dateien aus, die auf htm
enden. Zur Kontrolle sendet das Script HTML-Code an den Browser und gibt dabei alle eingelesenen Dateien aus.
Die folgende Tabelle enthält Beispiele für Dateimuster:
|
Die link-Funktion, die dem Unix-Befehl ln
entspricht, legt aus Sicht des Benutzers eine Kopie einer Datei an. Es handelt sich jedoch intern nach wie vor nur um eine einzige Datei, die lediglich nunmehr unter zwei verschiedenen Namen (und gegebenenfalls an zwei Stellen im Verzeichnisbaum zu finden ist. Wird die Datei an einer der Stellen, an denen sie repräsentiert wird, geändert, gilt die Änderung auch für die anderen Stellen, an denen die Datei repräsentiert wird. Wird eine der Dateien gelöscht (z.B. mit unlink), so bleiben andere Repräsentationen der Datei davon unberührt. Erst wenn die letzte Repräsentation der Datei gelöscht ist, ist die Datei endgültig gelöscht.
1. die bereits existierende Datei, von der eine neue Repräsentation erzeugt werden soll, wenn nötig mit Pfadangabe,
2. die neu zu erzeugende Repräsentation der Datei, wenn nötig mit Pfadangabe.
Gibt 1
zurück, wenn die Operation erfolgreich war, und 0
, wenn sie nicht erfolgreich war (z.B. weil im Zielverzeichnis kein Schreibrecht besteht).
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Erfolg = link("single.txt","../double.txt"); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; $Erfolg ? print "Erfolg" : print "kein Erfolg"; print "</body></html>\n"; |
Das Beispiel wendet die Funktion link
an, um von der Datei single.txt
im aktuellen Verzeichnis eine neue Repräsentation zu erzeugen, die im Verzeichnis oberhalb (../
) unter dem Namen double.txt
erscheint. Der Rückgabewert wird in dem Skalar $Erfolg
gespeichert. Zur Kontrolle sendet das Beispiel HTML-Code an den Browser und gibt dabei mit Hilfe einer einfachen Entweder-Oder-Abfrage den Erfolgsstatus der Operation aus.
Diese Funktion leistet das gleiche wie die Funktion stat. Nähere Beschreibung und Beispiel siehe dort.
Im Unterschied zu stat
ermittelt lstat
nicht die Eigenschaften einer Datei, sondern die einer Dateiverknüpfung, eines sogenannten symbolischen Links. Wenn es sich nicht um eine Repräsentation einer Datei handelt (also wenn die Datei nur einmal im Verzeichnisbaum erscheint), wird beim Aufruf von lstat
intern automatisch ein normaler Aufruf von stat
gestartet. lstat
erfaßt also im Gegensatz zu stat
auch Dateirepräsentationen und wird deshalb in der Praxis eher eingesetzt als stat
.
Legt ein neues Verzeichnis an und ermöglicht, für das neue Verzeichnis die Rechte für Lesen, Schreiben und Ausführen zu vergeben (nur bei Unix-Systemen wirksam).
Erwartet als Parameter:
1. den Namen des neuen Verzeichnisses, wenn nötig Pfadnamen.
2. eine Rechteangabe. Der Wert muss numerisch oktal übergeben werden, nicht als Zeichenkette! Zum Ermitteln der gewünschten Oktalzahl können Sie den Unix-Dateirechte-Setzer bei den kleinen Helferlein verwenden.
Auf Systemen, die keine Unix-Rechteverwaltung kennen, also z.B. unter MS Windows, ist der zweite Parameter bedeutungslos.
Gibt 1
bzw. TRUE
zurück, wenn die Operation erfolgreich war, und 0
bzw. FALSE
, wenn das Anlegen des Verzeichnisses nicht möglich war (z.B. weil in dem Verzeichnis, in dem das Unterverzeichnis angelegt werden sollte, kein Schreibrecht besteht). Der genaue Fehlertext kann in diesem Fall über die vordefinierte Variable $!
ermittelt werden.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my @Verzeichnisbaum = ( "texte", "texte/briefe", "texte/rechnungen", "texte/rechnungen/alt", "texte/rechnungen/neu", "grafiken", "grafiken/fotos", "grafiken/fotos/fremde", "grafiken/cliparts", ); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; chdir("/temp"); foreach(@Verzeichnisbaum) { mkdir($_,0777); print "Unterverzeichnis <b>$_</b> angelegt<br>\n"; } print "</body></html>\n"; |
Das Beispiel definiert eine Liste namens @Verzeichnisbaum
. Darin werden Einträge gespeichert, die eine anzulegende Unterverzeichnisstruktur darstellen. Weiter unten im Beispielscript wird diese Liste in einer foreach-Schleife abgearbeitet. Dabei wird jedes einzelne der Verzeichnisse mit mkdir
angelegt. Das jeweils aktuelle Verzeichnis der Liste steht innerhalb der Schleife in $_
. Als zweiter Parameter wird die Oktalzahl 0777
übergeben. Damit erhalten alle Benutzer der Verzeichnisse alle Rechte. Das Beispielscript sendet HTML-Code an den Browser und gibt für jedes angelegte Verzeichnis einen entsprechenden Satz aus.
List den Wert einer symbolischen Linkdatei aus. Das sind Linkdateien, die z.B. mit Hilfe von symlink erzeugt wurden.
Erwartet als Parameter:
1. den Namen der symbolischen Linkdatei, wenn nötig mit Pfadnamen.
Es ist auch möglich, keinen Parameter zu übergeben. In diesem Fall wird der Inhalt der vordefinierten Variablen $_
verwendet.
Gibt den vollständigen Pfad der Datei aus, auf die sich die Linkdatei bezieht. Im Fehlerfall gibt die Funktion undefined
zurück und schreibt den Fehlertext in die vordefinierte Variable $!
. Auf Betriebssystemen, die keine symbolischen Links kennen, also z.B. unter MS Windows, produziert der Aufruf dieser Funktion einen schweren Fehler.
#!/usr/bin/perl use strict; use CGI::Carp qw(fatalsToBrowser); chdir("/tmp"); symlink("/usr/local/webdocs/index.htm","webindex.sym"); my $Inhalt = readlink("webindex.sym"); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; print "Inhalt der symbolischen Datei: $Inhalt\n"; print "</body></html>\n"; |
Das Beispielscript wechselt zunächst mit chdir ins Verzeichnis /tmp
. Dort legt es mit symlink
eine symbolische Linkdatei namens webindex.sym
an, die ein symbolischer Link zu der Datei /usr/local/webdocs/index.htm
ist. Mit readlink
wird anschließend der Wert ausgelesen, der der symbolischen Datei zugeordnet ist. Zur Kontrolle sendet das Beispielscript HTML-Code an den Browser. Dabei wird der webindex.sym
zugeordnete Pfadnamen zur verlinkten Datei ausgegeben.
Erwartet als Parameter:
1. den Namen der umzubenennenden Datei oder des umzubenennenden Verzeichnisses, wenn nötig mit Pfadnamen.
2. den neuen Namen der Datei oder des Verzeichnisses, wenn nötig mit neuem Pfadnamen.
Wenn der erste Parameter eine Datei ist und der zweite Parameter der Name eines anderen Verzeichnisses, wird die Datei in das andere Verzeichnis verschoben. Es ist jedoch mit dieser Funktion nicht möglich, als ersten und zweiten Parameter zwei unterschiedliche Verzeichnisse anzugeben, um das erste Verzeichnis in das zweite zu verschieben.
Gibt true
zurück, wenn die Operation erfolgreich war, ansonsten false
.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); chdir("/htmldocs"); opendir(DIR,"."); my @Eintraege = readdir(DIR); closedir(DIR); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; my $Eintrag; my $Name; my $NeuerEintrag; foreach $Eintrag (@Eintraege) { if($Eintrag =~ /(.+)\.htm/) { $Name = $1; $NeuerEintrag = $Name.".html"; rename($Eintrag,$NeuerEintrag); print "$Eintrag in $NeuerEintrag umbenannt<br>\n"; } } print "</body></html>\n"; |
Das Beispiel bewirkt, dass alle Dateien eines Verzeichnisses, die auf die Endung .htm
enden, in gleichnamige Dateien mit der Endung .html
umbenannt werden.
Das Script wechselt zunächst mit chdir in das Verzeichnis /htmldocs
. Anschließend liest es dieses aktuelle Verzeichnis ("."
) in die Liste @Eintraege
ein (Erläuterungen zu diesen Befehlen siehe opendir). Das Beispielscript sendet HTML-Code an den Browser. Dabei werden die Einträge des eingelesenen Verzeichnisses in einer foreach-Schleife abgearbeitet. Bei jedem Eintrag wird geprüft, ob es sich um eine Datei mit der Endung .htm
handelt. Wenn ja, wird der "Vorname" der Datei in $Name
gespeichert und ein neuer Dateiname aus dem Wert von $Name
und der Endung .html
definiert. Anschließend wird die Funktion rename
aufgerufen. Dabei wird der bisherige Eintrag, also eine Datei .htm
, in den neuen Eintrag, also eine Datei mit gleichem Vornamen, nur mit der Endung .html
, umbenannt. Zur Kontrolle gibt das Script alle Umbenennungen aus.
Erwartet als Parameter:
1. den Namen des zu löschenden Verzeichnisses, wenn nötig Pfadnamen.
Das Verzeichnis muss leer sein, andernfalls kann es mit dieser Funktion nicht gelöscht werden.
Gibt 1
zurück, wenn das Verzeichnis gelöscht wurde. Falls ein Fehler aufgetreten ist, wird 0
zurückgegeben, und in der vordefinierten Variablen $!
steht die Fehlermeldung.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Verzeichnis = $ENV{'QUERY_STRING'}; my $Ergebnis = rmdir($Verzeichnis); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; if($Ergebnis == 1) { print "$Verzeichnis gelöscht!"; } else { print "$!"; } print "</body></html>\n"; |
Das Script beim Aufruf einen Übergabeparameter, der beim Aufruf über einen URI hinter einem Fragezeichen notiert wird. Der Übergabeparameter besteht in der Pfadangabe des zu löschenden Verzeichnisses. Beispiel:
/mydocs/texte/schrott
.
Das Script versucht, das übergebene Verzeichnis zu löschen. Der Rückgabewert des Versuchs wird in dem Skalar $Ergebnis
gespeichert.
Anschließend sendet das Script HTML-Code an den Browser. Dabei wird ausgegeben, ob das übergebene Verzeichnis erfolgreich gelöscht wurde oder nicht. Wenn nicht, wird die erzeugte Fehlermeldung ausgegeben.
Ermittelt diverse Eigenschaften einer Datei auf einmal in Listenform. Die meisten dieser Eigenchaften sind Unix-spezifisch. Einige Eigenschaften lassen sich zwar auch auf anderen Plattformen abfragen, doch dazu ist es eigentlich einfacher, die Dateitestoperatoren für Dateien/Verzeichnisse zu verwenden. Die Funktion stat
läßt sich im Gegensatz zu lstat nicht auf Dateirepräsentationen, sondern nur auf "Originale" von Dateien anwenden.
Erwartet als Parameter:
1. den Namen der gewünschten Datei, wenn nötig mit Pfadnamen. Alternativ kann auch der Names eines Datei-Handles übergeben werden.
Gibt eine Liste mit 13 Elementen zurück. Jedes Element enthält eine bestimmte, ermittelte Datei-Eigenschaft.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Datei = "/usr/webperldoc/index.html"; my @Info = stat($Datei); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body><pre>\n"; print "<b>Datei:</b> $Datei\n"; print "<b>Geraetetenummer:</b> $Info[0]\n"; print "<b>Inode-Nummer:</b> $Info[1]\n"; printf "<b>Zugriffsrechte:</b> %o\n", $Info[2]; print "<b>Anzahl Links auf Datei:</b> $Info[3]\n"; print "<b>User-ID des Besitzers:</b> $Info[4]\n"; print "<b>Gruppen-ID des Besitzers:</b> $Info[5]\n"; print "<b>Raw-Geraetenummer:</b> $Info[6]\n"; print "<b>Dateigroesse:</b> $Info[7]\n"; print "<b>Letzte Zugriffszeit:</b> $Info[8]\n"; print "<b>Letzte Aenderungsszeit:</b> $Info[9]\n"; print "<b>Inode-Aenderungsszeit:</b> $Info[10]\n"; print "<b>Ideale Blockgroesse:</b> $Info[11]\n"; print "<b>Anzahl belegter Blocks:</b> $Info[12]\n"; print "</pre></body></html>\n"; |
Das Beispiel ermittelt für eine bestimmte Datei (/usr/data/artikel.zip) mit stat
die verfügbaren Datei-Eigenschaften. Der Rückgabewert der Funktion wird in einer Liste @Info
gespeichert. Das Beispiel gibt HTML-Code an den Browser aus und listet dabei alle 13 Einzeleigenschaften, abrufbar über $Info[0]
bis $Info[12]
, auf. Die folgende folgende Tabelle enthält nähere Informationen über die einzelnen Eigenschaften.
|
Erzeugt einen symbolischen Link auf eine anderswo gespeicherte Datei. Der erzeugte Verzeichniseintrag erscheint jedoch im Gegensatz zu einem Eintrag, der mit link erzeugt wurde, nicht als tatsächliche Repräsentation der anderen Datei, sondern nur nur als Verknüpfung zu der anderen Datei (Unix-spezifisch).
Erwartet als Parameter:
1. die existierende Datei, zu der ein symbolischer Link erzeugt werden soll, wenn nötig mit Pfadangabe,
2. die neu zu erzeugende, symbolische Link-Datei, wenn nötig mit Pfadangabe.
Gibt 1
zurück, wenn die Operation erfolgreich war, und 0
, wenn sie nicht erfolgreich war. Auf Betriebssystemen, die keine symbolischen Links kennen, kann diese Funktion zu einem schweren Fehler beim Ausführen des Scripts führen!
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $symlink_exists = eval { symlink("",""); 1 }; if($symlink_exists) { symlink("/usr/local/people/stefan.htm","/usr/local/links/stefan.link"); } print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; opendir(DIR, "/u/web/teamon/temp"); my @Dateien = readdir(DIR); closedir(DIR); foreach (@Dateien) { print "$_<br>\n"; } print "</body></html>\n"; |
Das Beispiel überprüft zunächst mit Hilfe der Funktion eval, ob auf dem Betriebssystem, unter dem das Script ausgeführt wird, symbolische Links möglich sind. Benutzen Sie zu einer solchen Überprüfung den Befehl wie im Beispiel notiert. In dem Rückgabewert, der im Beispiel in dem Skalar $symlink_exists
gespeichert wird, steht der Wert 1 (true), falls symbolische Links möglich sind. Mit der Konstruktion if($symlink_exists)
ist dann die bedingte Ausführung von symlink
möglich. Im Beispiel wird eine Linkdatei namens stefan.link
erzeugt, die auf die Originaldatei stefan.htm
in einem anderen Verzeichnis zeigt. Das Beispiel liest zur Kontrolle das Verzeichnis, in dem die symbolische Linkdatei erzeugt wurde, ein (Erläuterungen zu diesen Befehlen siehe opendir) und sendet entsprechenden HTML-Code an den Browser.
Diese Funktion ist nur für Unix-Systeme relevant. Wenn unter Unix eine neue Datei geschrieben wird, werden die dabei vergebenen Zugriffsrechte durch die Umask des aktuell laufenden Prozesses (z.B. das laufende Perl-Script, das die Datei erzeugt) beeinflusst. Durch Aufruf der Funktion umask
können Sie die Umask des laufenden Prozesses ändern und dadurch dessen Wirkung auf die Zugriffsrechte neu erzeugter Dateien beeinflussen.
Erwartet als Parameter:
1. eine Bitmaske für eine Rechteangabe. Der Wert muss numerisch oktal übergeben werden. Jedes gesetzte Bit in der Bitmaske bewirkt, dass das entsprechende Bit in einer vom laufenden Prozess erzeugten Datei ausgeschaltet wird.
Gibt den alten Umask-Wert zurück.
#!/usr/bin/perl -w use strict; use Fcntl; sysopen(DATEI,"/usr/web/temp/test.txt", O_CREAT,0666); umask(0077); sysopen(DATEI2,"/usr/web/temp/test2.txt", O_CREAT,0666); open(LS,"ls -la /usr/web/temp |"); print while(<LS>); close(DATEI); close(DATEI2); close(LS); |
Das Beispiel erzeugt mit zwei Aufrufen von sysopen zwei Dateien namens test.txt
und test2.txt
. Bei beiden Dateien wird als gewünschte Rechte-Angabe 0666
angegeben. Zwischen den beiden Aufrufen von sysopen
steht jedoch ein Aufruf von umask
. Der Funktion wird dabei 077
als Oktalzahl mit führender 0
übergeben. Dies bewirkt, dass bei der Datei test2.txt
die tatsächlichen Zugriffsrechte auf 0600
gesetzt werden. Zur Kontrolle sendet das Script an den Browser das Ergebnis des Unix-Kommandos ls
für das Verzeichnis, in dem die beiden Dateien erzeugt wurden.
Die Wirkungsweise von umask
lässt sich besser verstehen, wenn man das Bitmuster der Oktalzahl aufschlüsselt und mit der Zeichenkettenschreibweise von Zugriffsrechten vergleicht.
Das Bitmuster der Oktalzahl 077
lautet: 000111111
(eine 7 ist 111 binär!).
Die Zeichenkettenschreibweise von 0666
lautet: rw-rw-rw-
.
Es stehen sich also 9 Bits und 9 Zeichen gegenüber. Jedes gesetzte Bit (1
) der Oktalzahl setzt das analoge Zeichen an der gleichen Stelle auf -
, sofern dort vorher r
, w
oder x
stand.
Das Bitmuster 000111111
bewirkt also bei einem Recht rw-rw-rw-
, dass alle hinteren 6 Zeichen auf -
gesetzt werden, so dass rw-------
herauskommt (was wiederum oktal 0600
entspricht).
Löscht eine oder mehrere Dateien gleichzeitig. Verzeichnisse können mit diesem Befehl nicht gelöscht werden, dazu steht die Funktion rmdir zur Verfügung.
Erwartet als Parameter:
1. eine Liste von Dateien, die gelöscht werden sollen.
Gibt die Anzahl der erfolgreich gelöschten Dateien zurück.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); chdir("/tmp"); opendir(DIR,"."); my @Eintraege = readdir(DIR); closedir(DIR); my $Anzahl = 0; foreach (@Eintraege) { unless( -d $_) { $Anzahl+= unlink($_); } } print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; print "$Anzahl Dateien entfernt!\n"; print "</body></html>\n"; |
Mit chdir wechselt das Beispielscript zunächst in das Verzeichnis, in dem etwas gelöscht werden soll. Anschließend wird das Verzeichnis mit opendir, readdir und closedir eingelesen. Die Verzeichniseinträge stehen anschließend in der Liste @Eintraege
. In einer foreach-Schleife wird die Liste sodann abgearbeitet. Mit unless( -d $_)
wird abgefragt, ob der aktuelle Eintrag kein Verzeichnis ist. Wenn das der Fall ist, wird der Eintrag, also eine Datei, mit unlink
gelöscht. Beim erfolgreichen Löschen wird die Variable $Anzahl
um 1 erhöht. Am Ende gibt das Script HTML-Code an den aufrufenden Browser aus und teilt die Anzahl gelöschter Dateien mit.
Ändert den Zeitstempel für den letzten Lesezugriff und den letzten Schreibzugriff von einer oder mehreren Dateien.
Erwartet als Parameter:
1. Eine Zeitangabe für den letzten Lesezugriff. Es muss sich um eine Sekundenangabe seit dem 1.1.1970 handeln, so wie ihn beispielsweise die Funktion time zurückgibt.
2. Eine Zeitangabe für den letzten Schreibzugriff. Auch dabei muss es sich um eine Sekundenangabe seit dem 1.1.1970 handeln.
3. eine Liste von Dateien, deren Zeitstempel geändert werden soll.
Gibt die Anzahl der erfolgreich "berührten" Dateien zurück.
#!/usr/bin/perl -w use strict; use CGI::Carp qw(fatalsToBrowser); my $Datei = $ENV{'QUERY_STRING'}; my $Jetzt = time(); utime($Jetzt,$Jetzt,$Datei); print "Content-type: text/html\n\n"; print '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">', "\n"; print "<html><head><title>Test-Ausgabe</title></head><body>\n"; print "Zeitstempel von $Datei wurde aktualisiert!\n"; print "</body></html>\n"; |
Das Script aktualisiert den Zeitstempel einer Datei. Beim Aufruf erwartet es einen Übergabeparameter, der beim URI hinter einem Fragezeichen notiert wird. Der Übergabeparameter besteht in der Pfadangabe einer Datei, deren Zeitstempel aktualisiert werden soll. Beispiel:
http://localhost/cgi-bin/test.pl?/mydocs/texte/wichtig.txt
. Den übergebenen Parameter speichert das Script in dem Skalar $Datei
. Um den aktuellen Zeitpunkt zu ermitteln, wird die Funktion time
aufgerufen. Sie liefert die Anzahl der Sekunden seit dem 1.1.1970 zurück, also genau die Form, utime
erwartet. Der Rückgabewert wird in $Jetzt
gespeichert. Nun kann das Script die utime
-Funktion aufrufen und ihr die gewünschten Parameter übergeben. Wenn Sie mehr als eine Datei auf einmal verarbeiten möchten, geben Sie die alle gewünschten Dateien durch Kommata getrennt an.
Anschließend sendet das Script HTML-Code an den Browser. Dabei wird das "Berühren" der Datei bestätigt.
Nicht alle Betriebssysteme unterscheiden wie Unix zwei verschiedene Zeitstempel. Unter Windows beispielsweise gibt es keinen Zeitstempel für den letzten Lesezugriff, nur für den letzten Schreibzugriff. Übergeben Sie utime
dennoch immer beide Parameter. Unter Windows wird dann nur der eine vorhandene Zeitstempel geändert.
Funktionen für Betriebssystemaufrufe | |
Funktionen für Ein-/Ausgabe und Lesen/Schreiben von Daten | |
SELFHTML/Navigationshilfen CGI/Perl Perl-Funktionen |
© 2001 selfhtml@teamone.de