Hansi: Perl Verzeichnisinhalt auflisten

Hallo an alle,

ich suche nach einer Möglichkeit, den Verzeichnisinhalt in eine Liste zu bekommen. Ähnlich wie der Befehl "ls -t -1". Ich kann schon gar nicht mehr sagen, was ich schon alles ausprobiert habe. Wenn möglich sollte kein Systemaufruf zu ls erfolgen.

Das Problem:
Mein Skript erstellt bei jedem Aufruf meiner Page ein temporäres Image, die dann in meiner Homepage angezeigt wird. Damit der Name der Datei auch zu 99,9% eindeutig ist, habe ich auf die Befehle srand() und rand() zurückgegriffen. Der daraus resultierende Dateiname lautet dann tmp568.2885087361252.gif. Jede Datei ist zwischen 1kb und 5kb groß. Bei ca. 1000 Dateien noch kein Problem auch bei 10000 auch kein Problem. Aber irgendwann sollte man daran denken aufzuräumen. Die Dateien werden sowieso nur so lange benötigt, wie die Seite selbst angezeigt wird. Ich möchte nun über die gesuchte Funktion eine Dateiliste erstellen, mit deren Hilfe dann die Dateien, die älter als xxx min/std. sind löschen.

Es gibt leider kein Beispiel im Netz, da ich bei mir einen Webserver zum testen aufgebaut habe. Meine Seiten sind noch nicht öffentlich.

Im voraus schon mal Danke für eure Antworten.
Hansi

  1. Hi,

    ich suche nach einer Möglichkeit, den Verzeichnisinhalt in eine Liste zu bekommen. Ähnlich wie der Befehl "ls -t -1". Ich kann schon gar nicht mehr sagen, was ich schon alles ausprobiert habe. Wenn möglich sollte kein Systemaufruf zu ls erfolgen.

    neben den "normalen" open()-Befehlen gibt es noch
    opendir(),
    readdir() und
    closedir().

    Beispiel:
    opendir(DIR,"/pfad/zu/deinem/verzeichnis");
    @dateien = readdir(DIR);
    closedir(DIR);

    Beachte, daß auch die Dateien "." und ".." in @dateien stehen.

    Cheatah

    1. Hallo Cheatah,

      Danke für Deine schnelle Antwort. Es hat funktioniert. Damit dies aber nicht nur eine Dankemeldung bleibt (ist glaube ich nicht so gerne gesehen), hier die kurze umsetzung der Lösung. Vielleicht kann noch jemand anderer davon profitieren.

      Einleitung:
      Bei der erstellung der temporären GIFs verwende ich GD.pm. Mit dieser Bibliothek erzeuge ich temporäre Images, die dann in der HTML-Seite angezeigt werden. Es muß für jede angezeigte Seite ein neues GIF erstellt werden. Die Namen der Dateien erzeuge ich mit srand() und rand(). Das ergab ursprünglich einen Dateinamen ähnlich wie tmp8736.98472574895.gif. Das Problem welches dabei auftaucht ist, daß das Verzeichnis, in das die Dateien kopiert werden irgendwann mal explodiert. Deshalb suchte ich nach einer Möglichkeit, Dateien in dem Verzeichnis, die älter als xxx Min/Std sind automatisch gelöscht werden, da diese ja nicht mehr benötigt werden.

      Durch dieses Konstrukt habe ich nun die Möglichkeit, # den Verzeichnisinhalt auszulesen.

      opendir(DIR,"/home/counterservice/www/digits/");
      @dateien = readdir(DIR);
      closedir(DIR);

      Um dann anschleßend in einer Datei zu speichern

      open (LOG, ">/home/counterservice/user/timesoft/counter/log/dir.txt");
      foreach $line (@dateien)
        {
        print LOG "$line\n";
        }
      close (LOG);

      Diese Dateiliste kann ich nun auslesen und die Dateien anhand des Dateinamens weierverarbeiten.

      Da es bei mir nun wichtig war, Dateien rauszufinden, die älter als xxx sind, habe ich die Dateinamen etwas verändert. so wird nun ein Dateiname nun um die Uhrzeit, die der Befehl time ausgibt, erweitert. Dabei entsteht nun ein Dateiname wie tmp929855463.0.9876254.gif.
      Wenn ich nun die Datei auslese, um die in Frage kommenden Dateien zu ermitteln, muß ich nur den Wert der Uhrzeit extrahieren und mit der aktuellen Zeit - xxx vergleichen. Wenn die überprüfte Datei dem kriterium entspricht, kann ich dann ie gewünscht mit ihr weiterverfahren. Bei mir eben Datei löschen.

      Also, noch einmal Dank für die schnelle Hilfe
      Hansi

      1. Hi,

        Danke für Deine schnelle Antwort. Es hat funktioniert. Damit dies aber nicht nur eine Dankemeldung bleibt (ist glaube ich nicht so gerne gesehen), hier die kurze umsetzung der Lösung. Vielleicht kann noch jemand anderer davon profitieren.

        och, ein kurzes Dankeswort alleine wäre schon okay gewesen :-) aber umso besser, hier kommt nämlich gleich noch was:

        [...] Die Namen der Dateien erzeuge ich mit srand() und rand().

        srand() brauchst Du nicht. Das wird bei der ersten Benutzung von rand() sowieso angestoßen; später ist es eher hinderlich, weil dadurch rand() gewissermaßen resettet wird und die selben Werte erneut kommen.

        Durch dieses Konstrukt habe ich nun die Möglichkeit, # den Verzeichnisinhalt auszulesen.

        opendir(DIR,"/home/counterservice/www/digits/");
        @dateien = readdir(DIR);
        closedir(DIR);

        Um dann anschleßend in einer Datei zu speichern

        Das brauchst Du eigentlich nicht, Du hast die Dateien doch schon im Speicher. Du kannst also foreach (@dateien) durchgehen.

        Da es bei mir nun wichtig war, Dateien rauszufinden, die älter als xxx sind, habe ich die Dateinamen etwas verändert. so wird nun ein Dateiname nun um die Uhrzeit, die der Befehl time ausgibt, erweitert. Dabei entsteht nun ein Dateiname wie tmp929855463.0.9876254.gif.

        (stat($file))[10] liefert (sinngemäß) die Erstellungszeit einer Datei. Ansonsten tut es vielleicht auch
        print (-M $file); # Age of file in days when script started.
        print (-A $file); # Same for access time.
        print (-C $file); # Same for inode change time.

        Die habe ich allerdings selbst noch nie benutzt; möglich, daß die Werte bei "zu jungen" Dateien alle Null sind. Prinzipiell ist die "-X"-Methode dem stat()-Befehl aber vorzuziehen.

        Cheatah

        1. Hallo,

          och, ein kurzes Dankeswort alleine wäre schon okay gewesen :-) aber umso besser, hier kommt nämlich gleich noch was:

          Nun wie man sieht, war es wohl doch sehr sinnvoll, die ganze Geschichte etwas auszuführen.(zumindest für mich) Wenn noch ein zwei andere User diesen Thread mitverfolgen und etwas neues erfahren war es ja mehr als sinnvoll. Ich z.B. suche zuerst alle mir zur Verfügung stehenden Informationsquellen durch bevor ich irgendwo konkret nachfrage. Bin halt schüchtern ;)

          srand() brauchst Du nicht. Das wird bei der ersten Benutzung von rand() sowieso angestoßen; später ist es eher hinderlich, weil dadurch rand() gewissermaßen resettet wird und die selben Werte erneut kommen.

          Interessante Info! Danke.

          Das brauchst Du eigentlich nicht, Du hast die Dateien doch schon im Speicher. Du kannst also foreach (@dateien) durchgehen.

          Stimmt! wäre ich bestimmt früher oder später auch darauf gekommen. Trotzdem Danke.

          (stat($file))[10] liefert (sinngemäß) die Erstellungszeit einer Datei. Ansonsten tut es vielleicht auch
          print (-M $file); # Age of file in days when script started.
          print (-A $file); # Same for access time.
          print (-C $file); # Same for inode change time.

          Die habe ich allerdings selbst noch nie benutzt; möglich, daß die Werte bei "zu jungen" Dateien alle Null sind. Prinzipiell ist die "-X"-Methode dem stat()-Befehl aber vorzuziehen.

          Na das ist wohl die Info des Jahres. Genau sowas habe ich gesucht. Danke.

          Hansi

      2. Hallo Hansi!

        Danke für Deine schnelle Antwort. Es hat funktioniert. Damit dies aber nicht nur eine Dankemeldung bleibt (ist glaube ich nicht so gerne gesehen), hier die kurze umsetzung der Lösung. Vielleicht kann noch jemand anderer davon profitieren.

        Na klar ist das gern gesehen! Es kommt oft vor, dass jemand eine Frage postet, jemand antwortet drauf, und dann bleibt dieser Zwei-Postings-Thread auf ewig so haengen. Man weiss nicht, ob die Antwort demjenigen geholfen hat, ja man weiss nicht mal, ob er sie ueberhaupt gelesen hat. Ist irgendwie auch ein doofes Gefuehl. Noch besser ist es natuerlich, wenn man wie Du dann auch noch die Problemloesung im ganzen mal kurz zusammenfasst. Es gibt naemlich durchaus Leute, die nicht auf solche Loesungen kommen, und denen nuetzt es sicher, wenn sie mal so ein Verfahren vorgestellt bekommen. Also danke fuer Deine Erklaerungen! :-)

        Calocybe

        1. Hallo Calocybe (schwerer Name)

          Na klar ist das gern gesehen! Es kommt oft vor, dass jemand eine Frage postet, jemand antwortet drauf, und dann bleibt dieser Zwei-Postings-Thread auf ewig so haengen. Man weiss nicht, ob die Antwort demjenigen geholfen hat, ja man weiss nicht mal, ob er sie ueberhaupt gelesen hat. Ist irgendwie auch ein doofes Gefuehl.

          Stimmt habe ich auch schon erlebt. Man weiß dann überhaupt nicht, hat es sich nun gelohnt zu antworten oder nicht.

          Noch besser ist es natuerlich, wenn man wie Du dann auch noch die Problemloesung im ganzen mal kurz zusammenfasst. Es gibt naemlich durchaus Leute, die nicht auf solche Loesungen kommen, und denen nuetzt es sicher, wenn sie mal so ein Verfahren vorgestellt bekommen.

          Nun, mir hat es schon öfters geholfen, wenn ich so ein Forum durchforste und dann die Lösungen auch nachvollziehen kann.

          Also danke fuer Deine Erklaerungen! :-)
          Gerne geschehen. Ich denke es ist mehr als selbstverständlich.

          Ich habe schon einige Foren durchforstet bin aber bis jetzt noch nirgend hängen geblieben. Meißtens arten die meißten Geschichten immer in wilden Haßtiraden aus. Da stehe ich überhaupt nicht darauf. Nicht daß ich was gegen Menschlichkeit hätte. Ich glaube Ihr habt hier das richtige Verhältnis zwischen Fachlichkeit und menschlichkeit gefunden.(Ausnahmen bestätigen die Regel) Es hat überigens auch sehr lange gedauert, bis ich mich getraut habe eine Frage bzw. einen Beitrag zu Posten.

          Gruß Hansi