Die unerklärlichen Mysterien des find Befehls?

Dieses Thema im Forum "Shell-Skripte" wurde erstellt von Crazy-X, 06.11.2005.

  1. #1 Crazy-X, 06.11.2005
    Crazy-X

    Crazy-X Grünschnabel

    Dabei seit:
    03.11.2003
    Beiträge:
    7
    Zustimmungen:
    0
    Hi,

    Der Betreff erklärt mein Problem eigentlich mehr als deutlich: Ich krieg' den find Befehl nicht auf die Reihe. Ich mein, welchen Stoff haben die Entiwckler davon denn gekifft, als sie das verbrochen haben? Logisch konsequent und inutuitiv ist die Bedinung von find jedenfalls nicht:

    Also ich habe mal zu Testzwecken ein paar Dateien (und Verzeichnisse) im System verteilt, die alle dem User "lionel" gehören:

    Code:
    me@zombie $ find / -xdev -user lionel
    /etc/fnord
    /etc/fnord2
    /mnt/blablub
    /usr/src/lionel_test
    /usr/fnord
    /usr/lionel_test2
    /usr/dir_lionel
    /usr/dir_lionel/blablub
    Jetzt möchte ich bei der Suche aber bestimmte Verzeichnisse ausschließen können. Kurz ge'google't und man findet folgende Lösung, aber scheinbar nirgendwo eine gute Erklärung dazu:

    Code:
    me@zombie $ find / -xdev -path /etc -prune -or -user lionel
    /etc
    /mnt/blablub
    /usr/src/lionel_test
    /usr/fnord
    /usr/lionel_test2
    /usr/dir_lionel
    /usr/dir_lionel/blablub
    Also einen Blick in "man find", was allerdings nicht den erhofften "Aha-Effekt" bringt sonder nur noch mehr verwirrung stiftet:

    Wieso hat "-prune" einen boolschen Wert und was zum Teufel hat das mit "-depth" zu tun?? Nach langem Überlegen habe ich mir das jetzt mal so erklärt:

    "-path /etc" = A
    "-prune" = B
    "-user lionel" = C

    Boolsche Gleichung:
    A ^ B v C ( A UND B ODER C)

    Falls A = 0 ist (das Verzeichnis ist nicht /etc), braucht der Ausdruck B nicht untersucht zu werden, da das Ergebnis von A ^ B bereits bekannt ist. Da aber noch ein Oder-Zweig existiert, der die ganze Gleichung noch wahr machen kann, wird der Ausdruck C ausgewertet.
    Falls das Verzeichnis aber "/etc" enthält (A = 1) MUSS B ausgewertet werden, um das Ergebnis von A ^ B bestimmen zu können. Und wenn er auf "-prune" trifft, lässt er das Verzeichnis aus. (Und da der erste Teil der Oder Gleichung dann wahr ist, muss C nicht mehr ausgewertet werden.)

    Stimmt das soweit? (Ich hoffe ich habe das mit der boolschen Gleichung nicht zu kompliziert gemacht...)

    Nun zu weiteren Abarten von find:

    Im 2. Befehl taucht ja jetzt trotzdem immer noch der Eintrag "/etc" auf. (Wieso eigentlich?) Dieser soll jetzt aber auch noch unterdrückt werden. Aus einem Skript (zudem ich evtl. in einem späteren Post noch ein paar Fragen habe) habe ich folgende Lösung:

    Code:
    me@zombie $ find / -xdev -path /etc -prune -path "/etc/*" -prune -or -user lionel
    /mnt/blablub
    /usr/src/lionel_test
    [...]
    Wieso funktioniert dieser Befehl nun, folgende aber nicht:

    Code:
    me@zombie $ find / -xdev -path "/etc*" -prune -or -user lionel
    me@zombie $ find / -xdev \( -path /etc -or -path "/etc/*" \) -prune -or -user lionel
    Obwohl auf vielen Seiten erklärt wird, dass man mit den Klammern mehrere Verzeichnisse auf einmal ausschließen kann. (Bei \( -path /etc -or -path /mnt \) funktionierts schließlich auch). Wie gesagt, logisch konsequent ist das wirklich nicht... :-((

    Ich hoffe hier kann mir jemand helfen. Bin echt schon seit mehreren Wochen am verzweifeln.

    TIA
    Crazy-X
     
  2. Anzeige

    Schau dir mal diese Kategorie an. Dort findest du bestimmt etwas.
    Registrieren bzw. einloggen, um diese und auch andere Anzeigen zu deaktivieren
  3. #2 Wolfgang, 06.11.2005
    Wolfgang

    Wolfgang Foren Gott

    Dabei seit:
    24.04.2005
    Beiträge:
    3.978
    Zustimmungen:
    0
    Ort:
    Erfurt
    Hallo
    Hoffe mal dir etwas Licht zu bringen.

    Zunächst ist es wichtig, sich zu verinnerlichen wie find seine Bedingungen abarbeitet.
    Alle Bedingungen werden von Links nach Rechts abgeklappert.
    Jeder Ausdruck der wahr ist, führt also zum nächsten Test.
    -depht:
    Veranlasst find erst den Inhalt zu testen, dann das Verzeichnis selbst.
    Wir steigen sozusagen von oben nach unten ab.
    Ein ausgeschlossenes Verzeichnis, was davor steht, wird zwar als Verzeichnis ausgeschlossen, aber erst nachdem der Inhalt getestet wurde!
    Alles was nun zutrifft gibt find aus bzw wertet weitere Tests aus!
    Ein in Klammern zusammengefasster Wert wird als Ganzes betrachtet.
    Das bedeutet, wenn der Ausdruck in den Klammern am Ende true liefert, wird nur der Wert true weiter ausgewertet.

    Einzelwerte innerhalb der Klammern sind danach transparent.

    Nun sollte auch klar werden, warum -prune false liefert, wenn -depht nicht gesetzt ist.
    Im Prinzip könntest du -prune mit einem AND ersetzen, mit einer Aussnahme: dass nämlich -depht berücksichtigt wird.

    Wenn -prune dann immernoch true liefern würde, würdest du unter Umständen -depth wirkungslos machen.

    Wir erinnern uns: -depth testet erst den Inhalt des Verzeichnisses, bevor es das Verzeichnis selbst testet!

    Das ist sozusagen eine Möglichkeit die von Links nach Rechts Regel zu umgehen.
    Sinnvoll ist das, wenn du z.B. Verzeichnisse mit -exec verschieben willst, weil sonst darin liegende Verzeichnisse nicht mehr gefunden würden.

    Hatten wir vor kurzer Zeit erst ein Beitrag hier im Forum.
    Hoffe dir etwas beim Verstehen geholfen zu haben.

    Gruß Wolfgang
     
  4. #3 Crazy-X, 07.11.2005
    Crazy-X

    Crazy-X Grünschnabel

    Dabei seit:
    03.11.2003
    Beiträge:
    7
    Zustimmungen:
    0
    Hi,

    also erstmal vielen Dank, für deine Hinweise und Tipps! Ich habe zwar eine Weile gebrauch und musste wirklich erstmal verinnerlichen wie find vorgeht. Allerdings habe ich mal noch ein paar Fragen, ob ich das richtig verstanden habe.

    Davon ausgehend, dass der Verzeichnisbaum nur folgende Eintäge enthält, würde find also die Eintäger der folgenden Liste hintereinander abarbeiten:

    Code:
    /etc
    /etc/fnord
    /etc/fnord2
    /etc/testdir
    /etc/testdir/shouldnotbefound
    /mnt
    /mnt/blablub
    /usr
    /usr/src
    /usr/src/lionel_test
    /usr/fnord
    /usr/lionel_test2
    /usr/dir_lionel
    /usr/dir_lionel/blablub
    Bei einem "find / -xdev -path /etc -prune -or -user lionel" müsste also, wenn ich richtig verstanden habe, folgendes passieren:

    find gelangt zum Eintrag "/etc". Deshalb liefert (-path /etc) true, und prune wird ausgewertet. Da prune in diesem Fall true liefert, wird der gesamte Ausdruck (wegen dem Oder) wahr. Und deshalb wird auch /etc ausgegeben!? Dann überspringt find das Verzeichnis und macht mit "/mnt" weiter! Richtig?

    Damit aber auch die Ausgabe von "/etc" unterdrückt wird ist in diesem Befehl "find / -xdev -path /etc -prune -path "/etc/*" -prune -or -user lionel" weniger der Test "-path '/etc/*' " schuld, sondern eher der gesamt Ausdruck. Da bei /etc der Test -path "/etc/*" sowieso false ist, wird auch der Gesamtausdruck false (und deshalb auch die Ausgabe von /etc unterdrückt). Vereinfacht stellt der Befehl eigentlich nur das dar: "find / -xdev -path /etc -prune -false -or -user lionel" (wie "dreckig" ^^). Richtig?

    Und da bei "find / -xdev \( -path /etc -or -path "/etc/*" \) -prune -or -user lionel", das Verzeichnis "/etc" übersprungen wird, kann der Test -path "/etc/*" eigentlich sowieso nie true werden.

    Allerdings habe ich noch keine Idee, wie ich Verzeichnisse auch auschließen kann, wenn ich -depth benötige. Da werde ich aber erstnochmal selbst danach suchen.

    TIA
    Crazy-X
     
Thema:

Die unerklärlichen Mysterien des find Befehls?

Die Seite wird geladen...

Die unerklärlichen Mysterien des find Befehls? - Ähnliche Themen

  1. Samba erzeugt unerklärlichen Traffic

    Samba erzeugt unerklärlichen Traffic: Hallo, und zwar habe ich einen SAMBA-Dienst laufen welcher unentwegt Traffic mit den im Netz befindlichen Windowsrechnern erzeugt, am Tag...