SELFHTML: Perl / Funktionsreferenz / Funktionen für Datei- und Verzeichnis-Management
Author: Redaktion SELFHTML, selfhtml81@selfhtml.org
Description: Welche Funktionen es in Perl gibt, um Eigenschaften von Dateien und Verzeichnissen zu ermitteln und das Dateisystem zu verwalten.
Keywords: SELFHTML, Perl, Funktionen, Perl-Funktionen, Dateien, Verzeichnisse, Dateisystem, Dateiverwaltung, Dateitestoperatoren, chdir, chmod, chown, chroot, glob, link, lstat, mkdir, readlink, rename, rmdir, stat, symlink, umask, unlink, utime
Date: 2005-11-06T15:17:41+01:00

| # Funktionen für Datei- und Verzeichnis-Management
| Allgemeines zu diesen Funktionen -[x] - Dateitestoperatoren für Dateien/Verzeichnisse chdir - Verzeichnis wechseln chmod - Datei-/Verzeichnisrechte ändern chown - Besitzer und Besitzergruppe von Dateien ändern chroot - Wurzelverzeichnis für Pfadnamen ändern glob - Dateien mit Wildcards auswählen link - neue Datei als Link auf vorhandene erzeugen lstat - Eigenschaften einer Link-Datei mkdir - Verzeichnis erstellen readlink - Wert einer Link-Datei auslesen rename - Datei/Verzeichnis umbenennen rmdir - Verzeichnis löschen stat - Eigenschaften einer Datei ermitteln symlink - neue Datei als symbolischen Link auf vorhandene erzeugen umask - Umask des laufenden Prozesses ändern unlink - Dateien löschen utime - Zeitstempel von Dateien/Verzeichnissen ändern

## Allgemeines zu diesen Funktionen

Perl kommt, wie bereits mehrfach betont wurde, aus der Unix-Welt. Daher sind die Funktionen rund um Datei- und Verzeichnismanagement auch an den typischen Möglichkeiten von Unix orientiert. Einige dieser Funktionen sind nur anwendbar, wenn Ihr Perl-Script auf einem Unix-System ausgeführt wird. Funktionen zur Dateiverwaltung, die auch auf anderen Betriebssystemen ausführbar sind, können als "plattformunabhängig" bezeichnet werden, auch wenn das nicht absolut korrekt ist. Bei den hier aufgeführten Beschreibungen zu den einzelnen Funktionen zum Datei- und Verzeichnismanagement wird darauf hingewiesen, wenn es Beschränkungen auf bestimmte Betriebssystemtypen 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.

### Pfadnamen und Verzeichnisse:

Die hier beschriebenen Funktionen erwarten als Parameter Pfadangaben. Als Trennzeichen zwischen Verzeichnisnamen bei Pfadangaben benutzen Sie aus Portabilitätsgründen am besten grundsätzlich den einfachen Schrägstrich, auch bei Perl-Scripts, die unter Windows laufen sollen. Perl unter Windows setzt dies intern in die Microsoft-eigenen Backslashes um.
Beispiele:

Syntaxbeispiel | Bedeutung
--- | ---
`".."` | relative Angabe, ein Verzeichnis höher
`"../../bin"` | relative Angabe, zwei Verzeichnisse höher und von dort aus gerechnet Unterverzeichnis "bin"
`"images"` | relative Angabe, Unterverzeichnis "images" im aktuellen Verzeichnis
`"/"` | absolute Angabe, Wurzelverzeichnis
`"/usr/bin/perl"` | absolute Angabe ab Wurzelverzeichnis
`"c:/windows/system"` | absolute Angabe mit Laufwerksangabe - Windows-typisch

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`.

### Rechteangaben für Dateien und Verzeichnisse

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, also der Benutzer mit der so genannten root-Kennung, kann Benutzer und Benutzergruppen einrichten und manipulieren sowie 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. Grundsätzlich werden auf Unix-Systemen für jede Datei und jedes Verzeichnis die Zugriffsrechte für den besitzenden Benutzer, seine primäre Benutzergruppe und für Fremdbenutzer ("Rest der Welt") festgelegt. Dabei wird zwischen Leserecht, Schreibrecht und Ausführungsrecht unterschieden. 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 erfolgt ü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 solcher Buchstabe gesetzt, so ist damit das entsprechende Recht vergeben. Ist das entsprechende Recht nicht gesetzt, wird 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 also: 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". Die Ziffern haben folgende Bedeutung für die Rechtezuweisung:

- 1 für Ausführen (--x)
- 2 für Schreiben (-w-)
- 3 für Schreiben und Ausführen (-wx)
- 4 für Lesen (r--)
- 5 für Lesen und Ausführen (r-x)
- 6 für Lesen und Schreiben (rw-)
- 7 für Lesen, Schreiben und Ausführen (rwx)
- sowie 0 für nichts (---)

Der Wert `0777` bedeutet also: alle drei Benutzertypen (besitzender Benutzer, zugehörige Gruppe und Rest der Welt) haben an der Datei alle drei Rechte.
Der Wert `0644` bedeutet also: der besitzende Benutzer hat die Rechte "Lesen" und "Schreiben", seine Gruppe und der Rest der Welt haben nur das Recht "Lesen".
Der Wert `0700` bedeutet also: der besitzende Benutzer hat alle Rechte, seine Gruppe und der Rest der Welt haben überhaupt keine Rechte.

### Beachten Sie:

Als Hilfe für Dateirechte können Sie auch den Unix-Dateirechte-Setzer (chmod) benutzen.

## -[x] - Dateitestoperatoren für Dateien/Verzeichnisse

Die einfachste und schnellste Methode, 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. Eine Übersicht der Dateitestoperatoren finden Sie in der Tabelle der Dateitestoperatoren.

### Beispiel 1 eines vollständigen CGI-Scripts in Perl:

    #!/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 $Perl-Datei = "/usr/webcgi-local/betrag.pl";
    my $Log-Datei = "/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 Perl-Datei ",-e $Perl-Datei ? "existiert<br>\n" : "existiert nicht<br>\n";
    print "Es hat Zugriffe gegeben" if not -z $Log-Datei;
    print "</body></html>\n";

### Erläuterung:

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 ausgegeben. Dabei werden verschiedene Aussagen über Eigenschaften der drei Dateien getroffen.
Die erste `print`-Anweisung enthält als 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 Perl-Datei 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, dass es Zugriffe gegeben hat.

### Beachten Sie:

Dateitestoperatoren können auch vergebene Datei-Handles 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.

### Tabelle der Dateitestoperatoren:

Syntax | Bemerkung | Bedeutung | Beispiel | Erläuterung
--- | --- | --- | --- | ---
`-A` |  | ermittelt, wie lange seit Programmstart auf eine Datei zugegriffen wurde. Rückgabewert ist die Zeit in Tagen als Gleitpunktzahl. | `printf("%.3f Tage Zugriffszeit",-A $Datei);` | Für die vom Script verarbeitete Datei `$Datei` wird ausgegeben, wie lange darauf zugegriffen wurde.
`-B` |  | ermittelt, ob es sich um eine Binärdatei handelt. | `binmode(FILE) if -B FILE;` | Wenn die Datei des File-Handles FILE eine Binärdatei ist, wird `binmode` aufgerufen.
`-b` | Unix- spezifisch | ermittelt, ob eine Gerätedatei blockorientiert ist. | `exit(-1) unless -b "/cdrom";` | Wenn "/cdrom" kein blockorientiertes Gerät ist, wird das Script beendet.
`-C` |  | ermittelt die Inode-Veränderungszeit einer Datei seit Programmstart. Rückgabewert ist die Zeit in Tagen als Gleitpunktzahl. | `if(-C $Datei > 10) { print "Warnung!"; }` | Wenn die Inode-Zeit der Datei `$Datei` größer als 10 Tage ist, wird "Warnung!" ausgegeben.
`-c` | Unix- spezifisch | ermittelt, ob eine Gerätedatei zeichenorientiert ist. | `exit(-1) if -c "/cdrom";` | Wenn "/cdrom" zeichenorientiert ist, wird das Script beendet.
`-d` |  | ermittelt, ob es sich um ein Verzeichnis handelt. | `chdir("texte") if -d "texte";` | Wenn "texte" ein Verzeichnis ist, wird in das Verzeichnis gewechselt.
`-e` |  | ermittelt, ob ein Verzeichniseintrag existiert. | `print "text.txt existiert!" if -e "text.txt";` | Wenn die Datei "text.txt" existiert, wird dies ausgegeben.
`-f` |  | ermittelt, ob es sich um eine normale Datei (keine Gerätedatei, kein Verzeichnis usw.) handelt. | `Verarbeiten() if -f "text.txt";` | Wenn die Datei "text.txt" eine normale Datei ist, wird eine Subroutine aufgerufen.
`-g` | Unix- spezifisch | ermittelt, ob bei einer Datei das setgid-Bit (set-group-ID-Bit) gesetzt ist. | `chmod 02771, "daten" unless -g "daten";` | Wenn das Verzeichnis "daten" kein setgid-Bit besitzt, werden die entsprechenden Rechte gesetzt.
`-k` | Unix- spezifisch | ermittelt, ob bei einer Datei das Sticky-Bit gesetzt ist (Bit z.B. für die Anweisung, Code eines Programms nach dessen Ausführung im Speicher zu behalten, weil es voraussichtlich öfter ausgeführt wird). | `print "test.pl ist sticky" if -k "test.pl";` | Wenn die Datei "text.pl" das Sticky-Bit gesetzt hat, wird dies ausgegeben.
`-l` | Unix- spezifisch | ermittelt, ob es sich um einen symbolischen Link handelt. | `print readlink("text.txt") if -l "text.txt";` | Wenn die Datei "text.txt" ein symbolischer Link ist, wird dessen Wert ausgegeben.
`-M` |  | ermittelt, wie lange eine Datei seit Programmstart nicht geändert wurde. Rückgabewert ist die Zeit in Tagen als Gleitpunktzahl. | `printf("seit %.3f Tagen nicht modifiziert", -M $Datei);` | Für die Datei `$Datei` wird ausgegeben, wie lange sie nicht mehr verändert wurde.
`-o`/`-O` | Unix- spezifisch | ermittelt, ob die Datei der effektiven UID (`-o`) bzw. der realen UID (`-O`) gehört. | `Verarbeiten() if -o "text.txt";` | Wenn die Datei "text.txt" der effektiven UID gehört, wird eine Subroutine aufgerufen.
`-r`/`-R` | Unix- spezifisch | ermittelt, ob die effektive UID/GID (`-r`) bzw. die reale UID/GID (`-R`) Leserecht für die Datei besitzt. | `open(FILE,"<text.txt") if -r "text.txt";` | Wenn die effektive UID/GID Leserecht auf die Datei "text.txt" hat, wird sie zum Lesen geöffnet.
`-p` | Unix- spezifisch | ermittelt, ob es sich um eine named pipe (FIFO) handelt. | `print "pipe" if -p "myprog";` | Wenn die Datei "myprog" eine named pipe ist, wird dies ausgegeben.
`-S` | Unix- spezifisch | ermittelt, ob die Datei eine Socket-Datei ist (wird von Client-Server-Prozessen, die auf einem Rechner laufen, als Schnittstelle benutzt). | `next if -S $_;` | Wenn die aktuelle Datei innerhalb einer angenommenen Schleife zur Überprüfung von allen Verzeichniseinträgen ein Socket ist, startet der nächste Schleifendurchgang.
`-s` |  | ermittelt die Dateigröße in Bytes. | `print -s $DirEintrag if not -d $DirEintrag;` | Wenn der Verzeichniseintrag `$DirEintrag` kein Verzeichnis ist, wird die Dateigröße ausgegeben.
`-T` |  | ermittelt, ob es sich um eine Textdatei handelt. | `Verarbeiten() if -T "text.txt";` | Wenn die Datei "text.txt" eine Textdatei ist, wird eine Subroutine aufgerufen.
`-t` | Unix- spezifisch | ermittelt, ob der Verzeichniseintrag ein tty, d.h. ein angeschlossenes Gerät (Terminal) ist (unter Unix werden Peripheriegeräte als Dateien behandelt). | `print "STDIN ist tty" if -t "STDIN";` | Wenn der Standardeingabekanal tty ist, wird dies ausgegeben.
`-u` | Unix- spezifisch | ermittelt, ob bei einer Datei das setuid-Bit (Set-User-ID-Bit) gesetzt ist. | `die "kein uid-Bit" if not -u "text.pl";` | Wenn bei der Datei "text.pl" kein setuid-Bit gesetzt ist, wird das Script mit einer Fehlermeldung beendet.
`-w`/`-W` | Unix- spezifisch | ermittelt, ob die effektive UID/GID (`-w`) bzw. die reale UID/GID (`-W`) Schreibrecht für die Datei besitzt. | `open(FILE,">text.txt") if -W "text.txt";` | Wenn die reale UID/GID für die Datei "text.txt" Schreibrechte besitzt, wird sie zum Schreiben geöffnet.
`-x`/`-X` | Unix- spezifisch | ermittelt, ob die effektive UID/GID (`-x`) bzw. die reale UID/GID (`-X`) Ausführrecht für die Datei besitzt. | `system("myprog") if -x "myprog";` | Wenn die effektive UID/GID für die Datei "myprog" Rechte zum Ausführen der Datei besitzt, wird sie über einen `system`-Aufruf ausgeführt.
`-z` |  | ermittelt, ob eine Datei leer ist, also 0 Bytes hat. | `open(FILE,"<text.txt") if not -z "text.txt"` | Wenn die Datei "text.txt" nicht leer ist, wird sie zum Lesen geöffnet.

## chdir - Verzeichnis wechseln

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 kümmern zu müssen.

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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

Das Beispielscript 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 erzeugt. Dabei werden die Zeilen der eingelesenen Datei ausgegeben.

## chmod - Datei-/Verzeichnisrechte ändern

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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

Das Beispiel setzt alle Perl-Dateien 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 Perl-Datei mit den gewünschten Rechten versehen. Zur Kontrolle gibt das Beispielscript aus, welche Dateien geändert wurden.

## chown - Besitzer und Besitzergruppe von Dateien ändern

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 ändert 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 die angegebenen UID und GID gelten sollen, wenn nötig mit Pfadnamen.

Gibt die Anzahl der vorgenommenen Änderungen zurück.

### Beispiel:

    #!/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 $_;
    }

### Erläuterung:

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.

## chroot - Wurzelverzeichnis für Pfadnamen ändern

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.

### Beispiel:

    #!/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";
    }

### Erläuterung:

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).

## glob - Dateien mit Wildcards auswählen

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, dass 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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

Das Beispielscript wählt im Verzeichnis `/usr/web/docroot` alle Dateien aus, die auf `htm` enden. Zur Kontrolle gibt das Script HTML-Code mit allen eingelesenen Dateien aus.

Die folgende Tabelle enthält Beispiele für Dateimuster:

Dateimuster | Bedeutung
--- | ---
`*` | wählt alle Dateien und Verzeichnisse aus, auch solche, die keine Endung haben.
`*.*` | wählt alle Dateien und Verzeichnisse aus, die aus Namen und Endung bestehen.
`*.gif` | wählt alle GIF-Dateien aus
`index.*` | wählt alle Dateien aus, die `index` als Namen haben, unabhängig von der Endung.
`???.*` | wählt alle Dateien aus, deren Name aus drei Zeichen besteht, unabhängig von der Endung.
`????.txt` | wählt alle TXT-Dateien aus, deren Name aus vier Zeichen besteht.

## link - neue Datei als Link auf vorhandene erzeugen

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 dieser 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.

Erwartet als Parameter:
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).

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

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 erzeugt das Beispiel HTML-Code und gibt dabei mit Hilfe einer einfachen Entweder-Oder-Abfrage den Erfolgsstatus der Operation an.

## lstat - Eigenschaften einer Link-Datei

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 so genannten 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` erfasst also im Gegensatz zu `stat` auch Dateirepräsentationen und wird deshalb in der Praxis eher eingesetzt als `stat`.

## mkdir - Verzeichnis erstellen

Legt ein neues Verzeichnis an und ermöglicht es, 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 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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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 <strong>$_</strong> angelegt<br>\n";
    }
    print "</body></html>\n";

### Erläuterung:

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 erzeugt HTML-Code und gibt für jedes angelegte Verzeichnis einen entsprechenden Satz aus.

## readlink - Wert einer Link-Datei auslesen

Liest den Wert einer symbolischen Link-Datei aus. Das sind Link-Dateien, die z.B. mit Hilfe von symlink erzeugt wurden.

Erwartet als Parameter:
1. den Namen der symbolischen Link-Datei, 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 Link-Datei bezieht. Im Fehlerfall gibt die Funktion `undef` zurück und schreibt den Fehlertext in die vordefinierte Variable `$!`. Auf Betriebssystemen, die keine symbolischen Links kennen, also z.B. unter Windows, produziert der Aufruf dieser Funktion einen schweren Fehler.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

Das Beispielscript wechselt zunächst mit chdir ins Verzeichnis `/tmp`. Dort legt es mit `symlink` eine symbolische Link-Datei 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 erzeugt das Beispielscript HTML-Code. Dabei wird der `webindex.sym` zugeordnete Pfadnamen zur verlinkten Datei ausgegeben.

## rename - Datei/Verzeichnis umbenennen

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.
Es ist außerdem nicht möglich, Dateien auf eine andere Partition zu verschieben. Abhilfe schafft hierbei die Funktion `move` aus dem Standardmodul `File::Copy`.

Gibt `true` zurück, wenn die Operation erfolgreich war, ansonsten `false`.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

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 erstellt HTML-Code. 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 listet das Script alle Umbenennungen auf.

## rmdir - Verzeichnis löschen

Erwartet als Parameter:
1. den Namen des zu löschenden Verzeichnisses, wenn nötig den Pfadnamen.
Das Verzeichnis muss leer sein, andernfalls kann es mit dieser Funktion nicht gelöscht werden. Nicht leere Verzeichnisse lassen sich mit der Funktion `rmtree` aus dem Standardmodul `File::Path` löschen.

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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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&ouml;scht!";
    }
    else {
     print "$!";
    }
    print "</body></html>\n";

### Erläuterung:

Das Script erwartet 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 erzeugt das Script HTML-Code. Dabei wird ausgegeben, ob das übergebene Verzeichnis erfolgreich gelöscht wurde oder nicht. Wenn nicht, wird die erzeugte Fehlermeldung ausgegeben.

## stat - Eigenschaften einer Datei ermitteln

Ermittelt diverse Eigenschaften einer Datei auf einmal in Listenform. Die meisten dieser Eigenschaften 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ässt sich im Gegensatz zu lstat nicht auf Dateirepräsentanzen (symbolische links), 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 Name eines Datei-Handles übergeben werden.

Gibt eine Liste mit mehreren Elementen zurück. Jedes Element enthält eine bestimmte ermittelte Datei-Eigenschaft.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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 "<strong>Datei:</strong>                      $Datei\n";
    print "<strong>Geraetenummer:</strong>              $Info[0]\n";
    print "<strong>Inode-Nummer:</strong>               $Info[1]\n";
    printf "<strong>Zugriffsrechte:</strong>             %o\n", $Info[2];
    print "<strong>Anzahl Links auf Datei:</strong>     $Info[3]\n";
    print "<strong>User-ID des Besitzers:</strong>      $Info[4]\n";
    print "<strong>Gruppen-ID des Besitzers:</strong>   $Info[5]\n";
    print "<strong>Raw-Geraetenummer:</strong>          $Info[6]\n";
    print "<strong>Dateigroesse:</strong>               $Info[7]\n";
    print "<strong>Letzte Zugriffszeit:</strong>        $Info[8]\n";
    print "<strong>Letzte Aenderungsszeit:</strong>     $Info[9]\n";
    print "<strong>Inode-Aenderungsszeit:</strong>      $Info[10]\n";
    print "<strong>Ideale Blockgroesse:</strong>        $Info[11]\n";
    print "<strong>Anzahl belegter Blocks:</strong>     $Info[12]\n";
    print "</pre></body></html>\n";

### Erläuterung:

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 erzeugt HTML-Code und listet darin alle 13 Einzeleigenschaften, abrufbar über `$Info[0]` bis `$Info[12]`, auf. Die folgende Tabelle enthält nähere Informationen über die einzelnen Eigenschaften.

Indexnr.: | Erläuterung:
--- | ---
`[0]` | Gerätenummer: die systemweit eindeutige Gerätenummer des Dateisystems, auf dem sich die Datei befindet.
`[1]` | Inode-Nummer: Die dateisystemweit eindeutige Nummer der Datei innerhalb des Dateisystems mit der Gerätenummer aus [0].
`[2]` | Dateityp/Zugriffsrechte: Der zurückgegebene Wert muss als Oktalzahl interpretiert werden (daher im obigen Beispiel auch die Ausgabe mit printf als Oktalzahl). Die oktale Bewertung der Zahl zeigt zwar eine einzige Zahl, die jedoch aus zwei Teilen besteht. Die letzten drei Ziffern bedeuten die Rechteangaben zur Datei, und die Ziffern davor bedeuten den Dateityp. Die entsprechenden Nummern werden auf Unix-Systemen in der Datei `sys/stat.h` definiert.
`[3]` | Anzahl Links auf Datei: Anzahl physikalisch existierender Repräsentationen der Datei, also mindestens 1. Bei gesetzten Links, wie es in Perl z.B. mit der Funktion link möglich ist, erhöht sich die Anzahl.
`[4]` | User-ID des Besitzers: Die Nummer des Datei-Eigentümers.
`[5]` | Gruppen-ID des Besitzers: Die Nummer der Gruppe, zu der der Datei-Eigentümer gehört.
`[6]` | Raw-Gerätenummer: Nur bei Gerätedateien interessant.
`[7]` | Dateigröße: Die logische Größe der Datei in Bytes.
`[8]` | Letzte Zugriffszeit: Zeitstempel des letzten lesenden oder schreibenden Zugriffs auf die Datei. Die zurückgegebene Zahl bedeutet die Anzahl Sekunden seit dem 1.1.1970 bis zum Augenblick des letzten Zugriffs.
`[9]` | Letzte Änderungszeit: Zeitstempel des letzten schreibenden Zugriffs auf die Datei. Die zurückgegebene Zahl bedeutet die Anzahl Sekunden seit dem 1.1.1970 bis zum Augenblick des letzten Zugriffs.
`[10]` | Inode-Änderungszeit: Zeitstempel des letzten Zugriffs auf die Datei, der eine Änderung der Inode-Nummer bewirkte. Die zurückgegebene Zahl bedeutet die Anzahl Sekunden seit dem 1.1.1970 bis zum Augenblick der letzten Inode-Änderung.
`[11]` | Ideale Blockgröße: Die optimale Anzahl Bytes zum blockweisen Lesen oder Schreiben der Datei - in Perl mit Funktionen wie sysread oder syswrite.
`[12]` | Anzahl belegter Blöcke: Die Anzahl der vom Betriebssystem benutzen Speicherblöcke, um die Datei zu speichern.

## symlink - neue Datei als symbolischen Link auf vorhandene erzeugen

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 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!

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

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 Link-Datei 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 Link-Datei erzeugt wurde, ein (Erläuterungen zu diesen Befehlen siehe opendir) und gibt entsprechenden HTML-Code aus.

## umask - Umask des laufenden Prozesses ändern

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 deren Wirkung auf die Zugriffsrechte neu erzeugter Dateien beeinflussen.

Erwartet als Parameter:
1. eine Bitmaske für eine Rechteangabe. Der Wert muss 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.

### Beispiel:

    #!/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);

### Erläuterung:

Das Beispiel erzeugt mit zwei Aufrufen von sysopen zwei Dateien namens `test.txt` und `test2.txt`. Bei beiden Dateien wird als gewünschte Rechteangabe `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 gibt das Script das Ergebnis des Unix-Kommandos `ls` für das Verzeichnis, in dem die beiden Dateien erzeugt wurden, aus.

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, sodass `rw-------` herauskommt (was wiederum oktal `0600` entspricht).

## unlink - Dateien löschen

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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

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 mit der Anzahl der gelöschten Dateien aus.

## utime - Zeitstempel von Dateien/Verzeichnissen ändern

Ä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.

### Beispiel eines vollständigen CGI-Scripts in Perl:

    #!/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";

### Erläuterung:

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, die `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 alle gewünschten Dateien durch Kommata getrennt an.
Anschließend erzeugt das Script HTML-Code. Dabei wird das "Berühren" der Datei bestätigt.

### Beachten Sie:

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

© 2007 Impressum