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