PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : find -prune listet Subdirectories?



McHurt
06-02-2008, 18:20
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:

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:

#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

Aqualung
06-02-2008, 21:16
Du suchst:



-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

ContainerDriver
06-02-2008, 23:11
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:

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:

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

jan61
07-02-2008, 01:06
Moin,


Du suchst:


-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:
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 ;-)

ContainerDriver
07-02-2008, 01:43
Mir ist gerade noch etwas aufgefallen: der ganze Befehl funktioniert nur, wenn -prune nicht schon auf . anschlägt.

jan61
07-02-2008, 02:21
Moin,


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

McHurt
07-02-2008, 10:29
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:

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

jan61
08-02-2008, 01:58
Moin,


Nichts desto trotz habe ich nun eine Lösung für mein Problem gefunden:

find * -prune -type d -mtime +15Zwei 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 :rolleyes: - 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:
find . -type d ! -name . -prune -mtime +15 -printJan

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