Aus Linux-Magazin 01/2005

Aus dem Nähkästchen geplaudert: Find und Locate

Moderne Computer mit ihren viele GByte fassenden Festplatten enthalten Tausende von Dateien. Hier die Übersicht behalten – das bedeutet viel Arbeit. Zum Glück bietet Unix eine Reihe praktischer Tools zum Auffinden verlegter Files, allerdings bieten einige auch Sicherheitsrisiken.

Wer unter Linux nach Dateien sucht, erzielt sehr gute Ergebnisse am schnellsten auf der Kommandozeile. Den grafischen Benutzeroberflächen, wie der von KDE in Abbildung 1, fehlt es an vergleichbarer Funktionalität, Flexibilität und Geschwindigkeit.

Abbildung 1: Das KDE-Programm KFind bietet zwar ein sehr gutes Interface für das Finden von Dateien. Doch an die Flexibilität von Find kommt es nicht heran. Vor allem komplexe Ausdrücke meistert Find besser.

Abbildung 1: Das KDE-Programm KFind bietet zwar ein sehr gutes Interface für das Finden von Dateien. Doch an die Flexibilität von Find kommt es nicht heran. Vor allem komplexe Ausdrücke meistert Find besser.

Das wichtigste Kommando für die Suche nach Dateien heißt seit jeher »find«. Ohne Argumente aufgerufen findet es alle Dateien unterhalb des aktuellen Verzeichnisses. Wer in einem anderen Verzeichnis suchen will, übergibt dessen Namen als erstes Argument. Der Aufruf »find /home« gibt beispielsweise eine Liste aller Dateien und Verzeichnisse unterhalb von »/home« aus.

Doch seinen unschätzbaren Nutzen entfaltet Find erst, wenn der Anwender es mit einigen der vielfältigen Optionen füttert. Mit dem Argument »-name Pattern« legen Benutzer fest, dass Find nur die Dateien ausgeben soll, deren Namen mit dem Pattern übereinstimmen. Der Aufruf »find ~ -name \’*firefox*\’« findet alle Dateien im Homeverzeichnis des Benutzers, die die Zeichenfolge »firefox« in ihrem Namen enthalten.

Es empfiehlt sich übrigens grundsätzlich, derartige Argumente in doppelte oder besser noch in einfache Anführungszeichen zu setzen. Diese Vorgehensweise verhindert, dass die Shell einen Parameter wie »*firefox*« expandiert.

Find kennt drei Arten von Argumenten: Optionen, Tests und Aktionen. Optionen beeinflussen das Verhalten des Suchvorgangs, beschränken zum Beispiel die Anzahl der durchsuchten Unterverzeichnis-Ebenen oder den Suchbereich auf eine Festplattenpartition. Mit Tests beschränkt der Anwender die Suche auf bestimmte Dateien, etwa solche, die nicht älter als eine Woche sind: »find -mtime -8«. Dateien, die älter als eine Woche sind, zeigt das Programm mit »find -mtime +7«. Die Option »-atime« beachtet bei der Suche die letzte Zugriffszeit auf eine Datei.

Alles ist möglich

Die Tests verwenden Administratoren am häufigsten. Äußerst nützlich ist etwa die Beschränkung auf einen Typ mit »-type f« (findet nur Dateien), »-type d« (nur Verzeichnisse) oder »-type l« (nur Symlinks). Der pflichtbewusste Administrator sucht im Rahmen von Aufräumarbeiten hin und wieder nach Dateien, die nicht existenten Nutzern oder Gruppen gehören. Das erledigt der Befehl »find / -nouser -o -nogroup«.

Die Tests lassen sich außerdem durch logische Operatoren (Und, Oder, Nicht) verknüpfen, sodass sich fast beliebig komplexe Ausdrücke erstellen lassen. Die zwischen die Tests gesetzte Option »-o« ist ein logischer Oder-Operator, der die beiden Ausdrücke »-nouser« und »-nogroup« verbindet. Gleichfalls für Admins von höchstem Interesse ist die Suche nach Files mit gesetztem SUID- oder SGID-Bit. Das erledigt »find / -perm +6000 -ls«. Das angehängte »-ls« führt auf jede Datei ein »ls -lisd« aus.

Befehle ausführen

Aktionen beeinflussen die Ausgabe der Ergebnisse. Die Aktion »-exec Kommando« übergibt beispielsweise den Namen jedes gefundenen File an das Programm Kommando. Mit »-exec« lassen sich die Dateinamen als Argumente von Befehlen nutzen und sogar kleine Shellskripte erzeugen.

Aber Achtung: Die nahe liegende Idee, diese Funktionalität als Root zu verwenden, ist in öffentlich zugänglichen Verzeichnissen (wie »/tmp« oder den Heimatverzeichnissen der Benutzer) nicht empfehlenswert. Zwischen dem Auffinden des korrekten Dateinamens und dem Ausführen des zugehörigen Befehls liegt nämlich eine kurze Verzögerung, die geschickte Angreifer für ihre Zwecke ausnutzen. In der Vergangenheit gab es immer wieder erfolgreiche Angriffe auf Unix-Installationen, die Find für das Aufräumen von »/tmp« einsetzten.

Nach der Aktion »-exec« gibt der Anwender einen Befehl an, der als Platzhalter »{}« enthält. Diese beiden Klammern ersetzt das Programm durch den Namen der gefundenen Datei. Ein Semikolon schließt den Befehl ab, der Benutzer muss es aber mit einem Backslash vor der Shell schützen. Folgender Befehl ist eine Variante des DOS-Kommandos »ren *.txt *.bak«, das Dateien mit dem Namen »*.txt« in »*.txt.bak« umbenennt:

$ find . -name '*.txt' -exec mv {} 
{}.bak ;

Bei noch komplexeren Anforderungen bietet es sich unter Umständen an, die Ausgabe von Find als Basis für ein Shell-skript zu verwenden. Hier leistet der Befehl »-printf« gute Dienste. Der folgende Aufruf erzeugt eine Datei mit mehreren Programmaufrufen wie in Listing 1:

$ find /home/mas -type f -name '*.txt' 
-printf "mkdir -p /export/backup/%hncp 
-p %p /export/backup/%h/%f.copynn"

Über die hier nur angedeuteten Features hinaus bietet Find noch eine Vielzahl von Möglichkeiten. Allerdings hat das Programm einen ganz entscheidenden Nachteil: Es ist langsam. Find liest die zu durchsuchenden Verzeichnisse einzeln ein und muss für die anzuwendenden Tests unter Umständen auch die Inodes der Dateien lesen.

Wer nur einen kleinen Teil seines Heimatverzeichnisses mit ein paar hundert Dateien durchsucht, wird dadurch keine große Verzögerung spüren. Wenn es aber eine bestimmte Datei zu suchen gilt, die sich irgendwo im Dateisystem versteckt, muss das Programm tausende Inodes lesen, und das dauert eine Weile.

Listing 1: Von Find
erzeugtes Skript

01 mkdir -p /export/backup//home/mas
02 cp -p /home/mas/.emacs /export/backup//home/ mas/.emacs.copy
03 
04 mkdir -p /export/backup//home/mas
05 cp -p /home/mas/.fetchmailrc /export/backup//home/ mas/.fetchmailrc.copy

Locate findet Dateien schneller

Locate löst dieses Problem, indem es alle auf dem Computer gespeicherten Dateien mit dem Programm »updatedb« indiziert und ihre Namen in einer zentralen Datenbank ablegt. Für die Suche ist es nicht mehr nötig, alle Inodes, sondern nur eine einzige Datenbankdatei zu lesen. Das Suchergebnis liegt innerhalb von Sekundenbruchteilen vor, minutenlange Wartezeiten (mit Performance-Einbußen für die übrigen Nutzer oder Dienste) entfallen.

Locate hat aber auch einige Einschränkungen, die den Einsatz von Find nicht überflüssig machen. Statt der oben angedeuteten komplexen Befehlssprache von Find bietet Locate nur eine primitive Suche nach Bestandteilen von Dateinamen, denn die Datenbank speichert keine weiteren Informationen über Dateien, etwa Datum oder Größe.

Als Platzhalter stehen das Fragezeichen (für einen beliebigen Buchstaben) und das Sternchen (für beliebig viele beliebige Buchstaben) zur Verfügung. Die Platzhalter matchen hier (im Gegensatz zu den Shell-Platzhaltern) auch auf das Zeichen »/«:

$ locate /home/mas/*mail*
/home/mas/.fetchmailrc
/home/mas/.procmaildata-bulk
/home/mas/.procmaildata-inbox
/home/mas/.procmailrc

Zwei Voraussetzungen für den Einsatz von Locate sind zwar trivial, bereiten aber manchmal doch Probleme: Erstens installieren nicht alle Linux-Distributionen dieses Werkzeug. Zweitens wird die notwendige Datenbank normalerweise über Cron[1] aktualisiert. Wenn der Computer zu der festgelegten Zeit ausgeschaltet ist und die Distribution kein Anacron[1] oder ein ähnliches Tool zum Nachholen verpasster Cronjobs enthält, muss der Anwender die Aktualisierung von Hand mit dem Befehl »updatedb« übernehmen. (mwe)

Fremde
Dateien

Locate nutzt eine zentrale Datenbank. Daraus ergibt sich in bestimmten Umgebungen jedoch ein Sicherheitsproblem. Will ein Benutzer seine Dateien verstecken, setzt er die Rechte des übergeordneten Verzeichnisses entsprechend (»chmod go-rwx«). Für Befehle wie »find« und »ls« werden die enthaltenen Dateien unsichtbar, außer natürlich für den Eigentümer und Root.

Steht die Datei aber in der Locate-Datenbank, weil »updatedb« mit »root«-Rechten läuft (etwa aus der Crontab von Root), ist sie trotz der Rechte für jedermann sichtbar. Dabei erhält der Anwender zwar nur den Dateinamen, doch selbst der mag unter bestimmten Voraussetzungen vertraulich sein.

Abhilfe auf echten Multi-User-Systemen bieten die Parameter »–localuser« und »–netuser« beim Aufruf von »updatedb«. Sie erwarten als Argument einen Benutzernamen. Der sollte etwa »nobody« lauten, ein Systembenutzer, der nur wenige Rechte hat. Dadurch enthält die »locate«-Datenbank nur noch öffentlich sichtbare Dateien.

Infos

[1] Marc André Selig, “Aus dem Nähkästchen geplaudert: Cron, At, Anacron”: Linux-Magazin 11/04, S. 60

LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben