Anzeige:
Ergebnis 1 bis 8 von 8

Thema: find -prune listet Subdirectories?

  1. #1
    Registrierter Benutzer
    Registriert seit
    14.01.2004
    Beiträge
    27

    find -prune listet Subdirectories?

    Hallo zusammen,
    Folgende Ausganglage: Ich möchte per Shell (sh, Solaris 10) alle Verzeinisse im aktuellen Verzeichnis auflisten, welche älter als 15 Tage sind. Das klappt eigentlich auch mit folgendem Kommando:
    Code:
    find . -type d -mtime +15 -prune
    Per Zufall habe ich nun gesehen, dass wenn ich ein Touch auf ein Verzeichnis mache, dessen Unterverzeichnisse aufgelistet werden. Also zum Beispiel:
    Code:
    #find . -type d -mtime +15 -prune
    ./a
    ./b
    #touch b
    # find . -type d -mtime +15 -prune
    ./a
    ./b/c
    ./b/d
    #
    Weshalb ist dies so? Bzw. wie kann ich dies unterbinden, so dass gemäss obigem Beispiel nur ./a ausgegeben wird?

    Gruss

  2. #2
    Registrierter Benutzer Avatar von Aqualung
    Registriert seit
    28.01.2008
    Beiträge
    14
    Du suchst:

    Code:
     -maxdepth Ebenen
                  steigt  bis  zu  der  gegebenen  Zahl von Ebenen im
                  Verzeichnisbaum auf (in der Hierarchie ab);  bei  0
                  Ebenen  werden die Tests nur auf die in der Komman*
                  dozeile übergebenen  Dateien  und  Verzeichnisnamen
                  angewendet
    Gruß Aqualung

  3. #3
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Zitat Zitat von McHurt Beitrag anzeigen
    Hallo zusammen,
    Folgende Ausganglage: Ich möchte per Shell (sh, Solaris 10) alle Verzeinisse im aktuellen Verzeichnis auflisten, welche älter als 15 Tage sind. Das klappt eigentlich auch mit folgendem Kommando:
    Code:
    find . -type d -mtime +15 -prune
    Per Zufall habe ich nun gesehen, dass wenn ich ein Touch auf ein Verzeichnis mache, dessen Unterverzeichnisse aufgelistet werden. Also zum Beispiel:
    Code:
    #find . -type d -mtime +15 -prune
    ./a
    ./b
    #touch b
    # find . -type d -mtime +15 -prune
    ./a
    ./b/c
    ./b/d
    #
    Weshalb ist dies so?
    In der Manpage zu find taucht "-prune" als Aktion (ACTION) auf, d.h. -prune wird auf die gefundenen Dateien (= Dateien, die dem Suchmuster entsprechen) angewendet. Wenn man mit touch nun den Timestamp aktualisiert, wird das Verzeichnis aber nicht mehr gefunden.
    Ein gebrechlich Wesen ist der X-Server.

  4. #4
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von Aqualung Beitrag anzeigen
    Du suchst:
    Code:
     -maxdepth Ebenen
    ...
    ich glaube er sucht dann nur und findet nicht ;-) - die Option ist AFAIK eine GNU-Erweiterung und unter Solaris nicht verfügbar. Die -regex-Option, die aushelfen könnte übrigens lt. man-Page auch nicht :-(

    Du kannst also in Solaris wohl nicht verhindern, dass der find in die Verzeichnisse abtaucht. Und wie ContainerDriver schon erklärt hat, wirkt -prune nur dann, wenn ein Verzeichnis gefunden wurde, welches den angegebenen Tests entspricht, nur dann steigt find nicht ab.

    Also bleibt Dir nach meiner Meinung nur der Weg, dahinter einen grep zu hängen, der nur das durchlässt, was kein Unterverzeichnis ist:
    Code:
    find . -type d -mtime +15 -prune | grep '^\./[^/]*$'
    Dies ist aber unter Umständen sehr zeitraubend - nämlich dann, wenn sich darunter eine größere Verzeichnis-Struktur verbirgt. Zwar hilft -prune dabei, die Anzahl der durchsuchten Verzeichnisse zu verringern, aber eben nur, wenn da mal irgendwo ein aktualisiertes Verzeichnis auftaucht.

    In dem o. g. Fall sollte man vielleicht mal mit Möglichkeiten spielen, nicht den find zu nehmen, sondern den ls -ad, und dann in einer Schleife zu testen, ob das ein Verzeichnis ist und wann es zuletzt modifziert wurde (ggf. gegen eine Referenzdatei, die man sich per touch angelegt hat), könnte u. U. viel Zeit sparen.

    Jan

    P.S.: Die einfachste Variante ist aber wahrscheinlich, sich den GNU-find zu installieren ;-)

  5. #5
    Registrierter Benutzer Avatar von ContainerDriver
    Registriert seit
    10.01.2003
    Beiträge
    418
    Mir ist gerade noch etwas aufgefallen: der ganze Befehl funktioniert nur, wenn -prune nicht schon auf . anschlägt.
    Ein gebrechlich Wesen ist der X-Server.

  6. #6
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von ContainerDriver Beitrag anzeigen
    Mir ist gerade noch etwas aufgefallen: der ganze Befehl funktioniert nur, wenn -prune nicht schon auf . anschlägt.
    *g* - stimmt - aber das ändert nichts am Prinzip. Mit GNU-find setzt man dann eben noch -mindepth, mit dem Solaris-find wäre durch die regex im grep das aktuelle Verzeichnis ausgeschlossen (enthält keinen /).

    Jan

  7. #7
    Registrierter Benutzer
    Registriert seit
    14.01.2004
    Beiträge
    27
    Hallo zusammen,
    Danke erstmal für all die Antworten. Ja, das mit -maxdepth geht leider nicht, da es nicht GNU find ist. Ich rege mich immer wieder auf, die GNU-Erweiterungen sind eben schon nett. Nichts desto trotz habe ich nun eine Lösung für mein Problem gefunden:
    Code:
    find * -prune -type d -mtime +15
    Zwei Sachen habe ich falsch gemacht. Einerseits muss ich * anstatt . angeben, da der -prune Befehl sonst nicht richtig angewendet wird. Zusätzlich musste ich -prune an den Anfang nehmen, da ich merkt, dass hier die Reihenfolge eine Role spielte.
    Aber danke nochmals für alle Antworten.

    Gruss

  8. #8
    Registrierter Benutzer
    Registriert seit
    07.05.2007
    Beiträge
    656
    Moin,

    Zitat Zitat von McHurt Beitrag anzeigen
    Nichts desto trotz habe ich nun eine Lösung für mein Problem gefunden:
    Code:
    find * -prune -type d -mtime +15
    Zwei Sachen habe ich falsch gemacht. Einerseits muss ich * anstatt . angeben, da der -prune Befehl sonst nicht richtig angewendet wird. Zusätzlich musste ich -prune an den Anfang nehmen, da ich merkt, dass hier die Reihenfolge eine Role spielte.
    das ist aber nicht das Gleiche. Mit * statt . erwischst Du keine Pfadnamen, die mit einem Punkt beginnen (und der reinen Lehre entspricht das auch nicht - am Anfang sollte eigentlich EIN Startverzeichnis stehen, ich kann mich dunkel erinnern, dass ältere find-Versionen z. B. bei SINIX es überhaupt nicht mochten, wenn sie da mehrere Pfade vorfanden).

    Mit der Reihenfolge der Optionen hast Du natürlich völlig recht, das vergesse ich auch immer wieder gern. Die beiden Erkenntnisse zusammengeschmissen ergeben folgende Variante, die mit allen find-Versionen laufen sollte und auch .bla-Verzeichnisse berücksichtigt:
    Code:
    find . -type d ! -name . -prune -mtime +15 -print
    Jan

    EDIT: Mit dem * hast Du wahrscheinlich noch ein potenzielles Problem - die berühmte Fehlermeldung "argument list too long", wenn es seeehr viele Einträge im aktuellen Verzeichnis gibt (die maximale Länge des Puffers für die Kommandozeile und das Environment; Parameter ARG_MAX).
    Geändert von jan61 (08-02-2008 um 01:05 Uhr)

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •