Re: Ordner leeren (nicht löschen)

From: Oliver Fromme <olli(at)lurza.secnetix.de>
Date: Mon, 4 Jun 2007 16:25:40 +0200 (CEST)

Timm Wimmers wrote:
> Oliver Fromme schrieb:
> > find -d /masterfolder -depth +1 | xargs rm -r
>
> vielen Dank für deine hilfreichen Hinweise, insbesonders
> "-print0" bei find und "-0" bei xargs.
>
> Ist "-d" nicht gleichbedeutend wie "-depth" bzw. dessen
> veraltete Schreibweise? Und ist "-depth" nicht auch für
> die rückwärts gerichtete Bearbeitung von find
> verantwortlich (also erst Verzeichnisinhalte und dann
> erst das Verzeichnis selbst)?

Jein. Da gehen leider zwei verschiedene Dinge durcheinan-
der, die aus historischen Gründen ähnlich aussehen.

Grob unterteilen sich die Argumente des find(1)-Aufrufs ja
in drei Dringe:

$ find <Optionen> <Pfade> <Primaries>

Nun gibt es eine Reihe von Optionen, die es aus histori-
schen Gründen bzw. us Gründen der Standardkompatibilität
auch als Primary existieren (obwohl sie sich in beiden
Fällen wie eine globale Option verhalte). Dazu gehören
-d (Option) und -depth (Primary), die beide genau das-
selbe bewirken, nämlich dass die Reihenfolge der Rekur-
sion verändert wird: Es werden zuerst alle Dateien in
einem Unterverzeichnis ausgegeben, dann erst das Unter-
verzeichnis selbst. Ich ziehe es vor, in solchen Fällen
die Option zu verwenden (hier also -d), da es weniger
fehlerträchtig ist (und außerdem auch weniger Tipparbeit).

Dagegen ist -depth gefolgt von einer Zahl etwas völlig
anderes: Es gibt die Verzeichnistiefe einer Datei an.
»-depth +1« heißt also »Tiefe > 1« und ist somit gleich-
bedeutend mit »-mindepth 2«. Ich persönlich ziehe aber
ersteres vor, weil es portabler ist. -mindepth/-maxdepth
wurde irgendwann in gnu-find eingebaut (die übliche GNU-
Featuritis, ohne Sinn und Verstand), und die BSDler haben
es dann übernommen, weil einige Skripte es verwenden. Es
ist aber eigentlich völlig überflüssig, und find unter
Solaris z.B. kennt es nicht. (Andererseits kennt Solaris
auch kein -print0 und eine Reihe anderer nützlicher Dinge,
insofern muss man das wieder relativieren.)

> Ich habe es jetzt dank der hier gemachten Hinweise
> folgendermaßen hinbekommen:
>
> find /masterfolder -mindepth 2 -depth -print0 | xargs -0 rm -r

Das ist genau das gleiche, das ich vorschlug, nur anders
aufgeschrieben (-depth statt -d, -mindepth statt -depth n).

> Leert alle Verzeichnisse der ersten Ebene unterhalb von
> /masterfolder. Möchte ich zudem noch die Dateien die
> sich unterhalb von /masterfolder befinden löschen, muss
> ich folgendes nachschieben.
>
> find /masterfolder -maxdepth 1 -type f -print0 | xargs -0 rm

Ja, das geht. Alternativ kannst Du auch in einem ersten
Durchgang alle Dateien löschen, und in einem zweiten Durch-
gang alle Unterverzeichniss:

$ find -d /masterfolder -depth +0 -type f -print0 | xargs -0 rm
$ find -d /masterfolder -depth +1 -type d -print0 | xargs -0 rmdir

Das setzt natürlich voraus, dass sich in dem Verzeichnis-
baum tatsächlich nur Unterverzeichnisse und einfache Da-
teien befinden (und nicht etwa auch Sockets, FIFOs o.ä.).
Anderenfalls schreib besser »! -type d« statt »-type f«
(je nach Shell muss man hier das Ausrufezeichen quoten,
oder »-not« statt »!« schreiben, was aber auch wiederum
nicht portabel ist.)

> Das scheint zu funktionieren und wird von mir gerade
> intensiv getestet. Allerdings habe ich noch nicht
> rausgefunden, wie ich die Fehlermedlung von "rm"
> unterdrücke, wenn "find" nichtsfindet, also via "xargs"
> ein leeres Argument liefert (kann ja sein, dass die
> Verzeichnis der ersten Ebene schon leer waren).

Dann ist bei Dir noch irgendwas falsch. Wenn xargs vom
find gar nichts geliefert bekommt, ruft es rm auch nicht
auf. Kann man einfach testen:

$ find /var/empty -type f | xargs rm
$

Ergibt keine Fehlermeldung.

> > Das ganze hat übrigens wenig bis gar nichts mit der
> > Shell zu tun, sondern ist einfach nur eine Sache des
> > Zusammenspiels der beteiligten Tools (in diesem Fall
> > find, xargs und rm), und die sind in ihren jeweiligen
> > Manual-pages recht gut dokumentiert.
>
> Ja es ist richtig, dass die Tools gut dokumentiert sind,
> allerdings fehlt mir schlicht die Erfahrung um eben die
> Zusammenhänge zu erkennen. Ich weiß ja meist nicht mal
> genau nach welchem Parameter ich suchen soll, so hat
> "-print0" dank deiner Hinweise quasi eine semantische
> Sensation in meinem Kopf hervorgerufen. Ich musste
> mir zur Beruhigung erstmal einen Kaffee holen.

Sowas kann vorkommen. :-) Ich bin schon viele Jahre im Ge-
schäft, habe aber auch ab und zu noch solche Aha-Erlebnisse.

Es gibt so ein bis zwei Dutzend Kommandos, die man immer
wieder in verschiedenen Variation braucht, und bei denen
lohnt es sich, einmal die Manual-page durchzulesen (oder
auch nur zu überfliegen), um einen Eindruck davon zu ge-
winnen, was man damit alles anstellen kann. find(1) und
xargs(1) gehören dazu, da find|xargs eine ganz typische
UNIX-Kombination ist.

Wenn man einmal verstanden hat, was xargs genau tut und
wozu es gut ist, hat man schon das Gröbste überstanden.

> > Shell-Wildcards ("*" usw.) sollte man in Skripten übri-
> > gens vermeiden, soweit es geht. Damit kann man sich
> > nämlich leichter in den Fuß schießen, als man meistens
> > vermutet. (Tatsächlich fangen viele meiner eigenen
> > Skripte mit »set -f« an, um Wildcards ganz auszuschal-
> > ten, damit gar nicht erst etwas passieren kann.)
>
> Dass Wildcards mitunter unschöne Seiteneffekte erzeugen,
> habe ich mittlerweile auch festgestellt. Ich habe mir
> angewöhnt immer zuerst (und für lange Zeit) auf
> Dummydaten zu arbeiten, die das erwartete Szenario
> möglichst genau abbilden. Ich werde die hier gemachten
> Hinweise ganz bestimmt für meine weitere BSD-Laufbahn
> berücksichtige. Ich schwör!

Du kannst auch jederzeit gerne Fragen hier stellen, auch
wenn so Shell-Fragen eigentlich off-topic sind (sie sind
ja meistens nicht BSD-spezifisch). Aber bei Shell-Fragen
gibt es immer zahleiche Leute, die darauf antworten können
bzw. die Antworten ihrer Vorredner noch verbessern können.
Oder es zumindest glauben. ;-)

Gruß
   Olli

-- 
Oliver Fromme, secnetix GmbH & Co. KG, Marktplatz 29, 85567 Grafing b. M.
Handelsregister: Registergericht Muenchen, HRA 74606,  Geschäftsfuehrung:
secnetix Verwaltungsgesellsch. mbH, Handelsregister: Registergericht Mün-
chen, HRB 125758,  Geschäftsführer: Maik Bachmann, Olaf Erb, Ralf Gebhart
FreeBSD-Dienstleistungen, -Produkte und mehr:  http://www.secnetix.de/bsd
"And believe me, as a C++ programmer, I don't hesitate to question
the decisions of language designers.  After a decent amount of C++
exposure, Python's flaws seem ridiculously small." -- Ville Vainio
To Unsubscribe: send mail to majordomo(at)de.FreeBSD.org
with "unsubscribe de-bsd-questions" in the body of the message
Received on Mon 04 Jun 2007 - 16:27:06 CEST

search this site