Find/Ausgabe: Unterschied zwischen den Versionen
Keine Bearbeitungszusammenfassung |
|||
(9 dazwischenliegende Versionen desselben Benutzers werden nicht angezeigt) | |||
Zeile 1: | Zeile 1: | ||
== Ausgabe formatieren == | |||
; -print | ; -print | ||
gibt den vollständigen Pfadnamen der getesteten Datei auf die Standardausgabe | gibt den vollständigen Pfadnamen der getesteten Datei auf die Standardausgabe | ||
Zeile 16: | Zeile 16: | ||
; -printf | ; -printf | ||
Using the (non-standard) “''‑printf''” action instead of the default “''‑print''” is useful to control the output format better than you can with the ''ls'' or ''dir'' utilities | Using the (non-standard) “''‑printf''” action instead of the default “''‑print''” is useful to control the output format better than you can with the ''ls'' or ''dir'' utilities | ||
* You can use ''find'' with the ''‑printf'' action to produce output that can easily be parsed by other utilities or imported into spreadsheets or databases | * You can use ''find'' with the ''‑printf'' action to produce output that can easily be parsed by other utilities or imported into spreadsheets or databases | ||
* See the Gnu ''find'' man page for the dozens of possibilities with the ''‑printf'' action | * See the Gnu ''find'' man page for the dozens of possibilities with the ''‑printf'' action | ||
* In fact, ''find'' with ''‑printf'' is more versatile than ''ls''; it is the preferred tool for forensic examiners even on Windows systems, to list file information.</nowiki> | * In fact, ''find'' with ''‑printf'' is more versatile than ''ls''; it is the preferred tool for forensic examiners even on Windows systems, to list file information.</nowiki> | ||
* For example the following displays non-hidden (no leading dot) files in the current directory only (no subdirectories), with an custom output format: find . -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n' | * For example the following displays non-hidden (no leading dot) files in the current directory only (no subdirectories), with an custom output format: find . -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n' | ||
“''‑maxdepth''” is a Gnu extension | “''‑maxdepth''” is a Gnu extension | ||
* On a modern, POSIX version of ''find'' you could use this: find . -path './*' -prune | * On a modern, POSIX version of ''find'' you could use this: find . -path './*' -prune | ||
* On any version of ''find'' you can use this more complex (but portable) code: find . ! -name . -prune | * On any version of ''find'' you can use this more complex (but portable) code: find . ! -name . -prune | ||
* which says to “prune” (don't descend into) any directories except “''.''” | * which says to “prune” (don't descend into) any directories except “''.''” | ||
* Note that “''‑maxdepth 1''” will include “''.''” unless you also specify “''‑mindepth 1''” | * Note that “''‑maxdepth 1''” will include “''.''” unless you also specify “''‑mindepth 1''” | ||
* A portable way to include “''.''” is: find . \( -name . -o -prune \) | * A portable way to include “''.''” is: find . \( -name . -o -prune \) | ||
* The “''\(''” and “''\)''” are just parenthesis used for grouping, and escaped from the shell | * The “''\(''” and “''\)''” are just parenthesis used for grouping, and escaped from the shell | ||
* The “''‑o''” means Boolean ''OR'' | * The “''‑o''” means Boolean ''OR'' | ||
* As a system administrator, you can use ''find'' to locate suspicious files (e.g., world writable files, files with no valid owner and/or group, Set files, files with unusual permissions, sizes, names, or dates) | * As a system administrator, you can use ''find'' to locate suspicious files (e.g., world writable files, files with no valid owner and/or group, Set files, files with unusual permissions, sizes, names, or dates) | ||
* Here's a more complex example (which I saved as a shell script so I can run it often): find / -noleaf -wholename '/proc' -prune \ -o -wholename '/sys' -prune \ -o -wholename '/dev' -prune \ -o -wholename '/windows-C-Drive' -prune \ -o -perm -2 ! -type l ! -type s \ ! \( -type d -perm -1000 \) -print | * Here's a more complex example (which I saved as a shell script so I can run it often): find / -noleaf -wholename '/proc' -prune \ -o -wholename '/sys' -prune \ -o -wholename '/dev' -prune \ -o -wholename '/windows-C-Drive' -prune \ -o -perm -2 ! -type l ! -type s \ ! \( -type d -perm -1000 \) -print | ||
* This says to seach the whole system, skipping the directories ''/proc'', ''/sys'', ''/dev'', and ''/windows-C-Drive'' (presumably a Windows partition on a dual-booted computer) | * This says to seach the whole system, skipping the directories ''/proc'', ''/sys'', ''/dev'', and ''/windows-C-Drive'' (presumably a Windows partition on a dual-booted computer) | ||
* The Gnu ''‑noleaf'' option tells ''find'' not to assume all remaining mounted filesystems are Unix file systems (you might have a mounted CD for instance) | * The Gnu ''‑noleaf'' option tells ''find'' not to assume all remaining mounted filesystems are Unix file systems (you might have a mounted CD for instance) | ||
* The “''‑o''” is the Boolean OR operator, and “''!''” is the Boolean NOT operator (applies to the following criteria) | * The “''‑o''” is the Boolean OR operator, and “''!''” is the Boolean NOT operator (applies to the following criteria) | ||
* So these criteria say to locate files that are world writable (“''‑perm ‑2''”, same as “''‑o=w''”) and NOT symlinks (“''! ‑type l''”) and NOT ''sockets'' (“''! ‑type s''”) and NOT directories with the ''sticky'' (or ''text'') bit set (“''! \( ‑type d ‑perm ‑1000 \)''”) | * So these criteria say to locate files that are world writable (“''‑perm ‑2''”, same as “''‑o=w''”) and NOT symlinks (“''! ‑type l''”) and NOT ''sockets'' (“''! ‑type s''”) and NOT directories with the ''sticky'' (or ''text'') bit set (“''! \( ‑type d ‑perm ‑1000 \)''”) | ||
(Symlinks, sockets, and directories with the sticky bit set, are often world-writable and generally not suspicious.) | (Symlinks, sockets, and directories with the sticky bit set, are often world-writable and generally not suspicious.) | ||
; -printf Format | ; -printf Format | ||
gibt für die getestete Datei die Zeichenkette Format auf der Standardausgabe aus; Format kann verschiedene Sonderzeichen und Platzhalter enthalten, die von find bearbeitet werden | gibt für die getestete Datei die Zeichenkette Format auf der Standardausgabe aus; Format kann verschiedene Sonderzeichen und Platzhalter enthalten, die von find bearbeitet werden | ||
\aAlarmton \bRückschritt \cAbbruch der Ausgabe \fSeitenvorschub \nZeilenvorschub \rWagenrücklauf \thorizontaler Tabulator \vvertikaler Tabulator \\der Backslash selbst | \aAlarmton \bRückschritt \cAbbruch der Ausgabe \fSeitenvorschub \nZeilenvorschub \rWagenrücklauf \thorizontaler Tabulator \vvertikaler Tabulator \\der Backslash selbst | ||
* ein Backspace gefolgt von irgendeinem anderen Zeichen wird als normales Zeichen interpretiert und einfach ausgegeben | * ein Backspace gefolgt von irgendeinem anderen Zeichen wird als normales Zeichen interpretiert und einfach ausgegeben | ||
%% das Prozentzeichen selbst %a die Zeit des letzten Zugriffs auf die Datei, in dem Format der ctime Funktion %A k die Zeit des letzten Zugriffs auf die Datei, in dem von k bestimmte Format; k hat dabei das gleiche Format wie der entsprechende Parameter der strftime Funktion in C | %% das Prozentzeichen selbst %a die Zeit des letzten Zugriffs auf die Datei, in dem Format der ctime Funktion %A k die Zeit des letzten Zugriffs auf die Datei, in dem von k bestimmte Format; k hat dabei das gleiche Format wie der entsprechende Parameter der strftime Funktion in C | ||
@ Sekunden seit dem 1.1.1970 0 Uhr GMT H Stunde (00 bis 23) I Stunde (01 bis 12) k Stunde (0 bis 23) l Stunde (1 bis 12) M Minute (00 bis 59) p PM oder AM r Zeit, 12 Stunden (hh:mm:ss: AM/PM) S Sekunden (00 bis 61) T Zeit, 24 Stunden (hh:mm:ss) X Zeit (H:M:S) Z Zeitzone, oder nichts a abgekürzter Wochentag A ausgeschriebener Wochentag b abgekürzter Monatsname B ausgeschriebener Monatsname c Datum und Zeit d Tag im Monat D Datum (mm/dd/yy) h das gleiche wie b j der Tag im Jahr m die Zahl des Monats U die Nummer der Woche, Sonntag als erster Wochentag w die Zahl des Wochentags W die Nummer der Woche, Montag als erster Wochentag x Datum (mm/dd/yy) y die letzten beiden Stellen der Jahreszahl Y die Jahreszahl | @ Sekunden seit dem 1.1.1970 0 Uhr GMT H Stunde (00 bis 23) I Stunde (01 bis 12) k Stunde (0 bis 23) l Stunde (1 bis 12) M Minute (00 bis 59) p PM oder AM r Zeit, 12 Stunden (hh:mm:ss: AM/PM) S Sekunden (00 bis 61) T Zeit, 24 Stunden (hh:mm:ss) X Zeit (H:M:S) Z Zeitzone, oder nichts a abgekürzter Wochentag A ausgeschriebener Wochentag b abgekürzter Monatsname B ausgeschriebener Monatsname c Datum und Zeit d Tag im Monat D Datum (mm/dd/yy) h das gleiche wie b j der Tag im Jahr m die Zahl des Monats U die Nummer der Woche, Sonntag als erster Wochentag w die Zahl des Wochentags W die Nummer der Woche, Montag als erster Wochentag x Datum (mm/dd/yy) y die letzten beiden Stellen der Jahreszahl Y die Jahreszahl | ||
Zeile 90: | Zeile 90: | ||
; -prune | ; -prune | ||
Wenn die Datei ein Verzeichnis ist, wird nicht in dieses hinabgestiegen. * wahr, wenn die Option -depth nicht angegeben ist | Wenn die Datei ein Verzeichnis ist, wird nicht in dieses hinabgestiegen. * wahr, wenn die Option -depth nicht angegeben ist | ||
* falsch, wenn die Option -depth angegeben ist, hat keine Auswirkungen | * falsch, wenn die Option -depth angegeben ist, hat keine Auswirkungen | ||
; Beispiele | ; Beispiele | ||
Ohne weitere Angaben gibt find die Namen der gefundenen Dateien aus: find /boot/grub/ -name "he*" /boot/grub/hexdump.mod /boot/grub/hello.mod /boot/grub/help.mod | Ohne weitere Angaben gibt find die Namen der gefundenen Dateien aus: find /boot/grub/ -name "he*" /boot/grub/hexdump.mod /boot/grub/hello.mod /boot/grub/help.mod | ||
* Wie bereits gesehen kann man mit ''-ls'' eine detailliertere Ausgabe erzeugen: find /boot/grub/ -name "he*" -ls 168624 4 -rw-r--r-- 1 root root 3196 Jan 13 17:08 /boot/grub/hexdump.mod 168603 4 -rw-r--r-- 1 root root 1308 Jan 13 17:08 /boot/grub/hello.mod 168623 4 -rw-r--r-- 1 root root 2200 Jan 13 17:08 /boot/grub/help.mod | * Wie bereits gesehen kann man mit ''-ls'' eine detailliertere Ausgabe erzeugen: find /boot/grub/ -name "he*" -ls 168624 4 -rw-r--r-- 1 root root 3196 Jan 13 17:08 /boot/grub/hexdump.mod 168603 4 -rw-r--r-- 1 root root 1308 Jan 13 17:08 /boot/grub/hello.mod 168623 4 -rw-r--r-- 1 root root 2200 Jan 13 17:08 /boot/grub/help.mod | ||
* Mit ''-exec'' und dessen Varianten lassen sich beliebige Programme auf den Fundstellen ausführen | * Mit ''-exec'' und dessen Varianten lassen sich beliebige Programme auf den Fundstellen ausführen | ||
* Die Anzahl der Zeilen in Textdateien findet man mit ''wc -l DATEI''; kombiniert mit find sieht das so aus: </nowiki> | * Die Anzahl der Zeilen in Textdateien findet man mit ''wc -l DATEI''; kombiniert mit find sieht das so aus: </nowiki> | ||
find -name "*.py" -exec wc -l {} \; 10 ./x/abc.py 6 ./x/date-form.py 102 ./x/download.py | find -name "*.py" -exec wc -l {} \; 10 ./x/abc.py 6 ./x/date-form.py 102 ./x/download.py | ||
* Das Kommando ''wc -l'' (Anzahl der Zeilen zählen) wird auf jede gefundene Datei angewandt | * Das Kommando ''wc -l'' (Anzahl der Zeilen zählen) wird auf jede gefundene Datei angewandt | ||
* Die geschweiften Klammern werden durch die von find gefundenen Namen ersetzt | * Die geschweiften Klammern werden durch die von find gefundenen Namen ersetzt | ||
* Am Ende muss der ganze Befehl mit einem Semikolon abgeschlossen werden | * Am Ende muss der ganze Befehl mit einem Semikolon abgeschlossen werden | ||
* Damit das Semikolon nicht von der Shell interpretiert wird, muss man es mit einem Backslash oder Anführungsstrichen maskieren | * Damit das Semikolon nicht von der Shell interpretiert wird, muss man es mit einem Backslash oder Anführungsstrichen maskieren | ||
* Kombination mit ''-print'' find tmp -name "a" -exec touch {} \; -print ./tmp/a ./tmp/a/a ./tmp/a/a/a | * Kombination mit ''-print'' find tmp -name "a" -exec touch {} \; -print ./tmp/a ./tmp/a/a ./tmp/a/a/a | ||
''touch'' setzt das Datum der Dateien auf den Ausführungszeitpunkt | ''touch'' setzt das Datum der Dateien auf den Ausführungszeitpunkt | ||
* Da touch aber nicht den Dateinamen ausgibt sieht man nicht, welche Dateien nun betroffen waren | * Da touch aber nicht den Dateinamen ausgibt sieht man nicht, welche Dateien nun betroffen waren | ||
* Daher schickt man ein ''-print'' hinterher | * Daher schickt man ein ''-print'' hinterher | ||
== Ausgabe sortieren == | |||
$ '''find -type f -print0 | xargs -0 stat -c "%y %n" | sort -r | head -20''' | $ '''find -type f -print0 | xargs -0 stat -c "%y %n" | sort -r | head -20''' | ||
==== Sort by size==== | |||
$ '''find -type f -exec ls -ltu {} \; | sort -k 5 -n''' | $ '''find -type f -exec ls -ltu {} \; | sort -k 5 -n''' | ||
==== Sort by access time==== | |||
$ '''find -type f -exec ls -ltu {} \; | sort -k 6 -M''' | $ '''find -type f -exec ls -ltu {} \; | sort -k 6 -M''' | ||
==== Search recursively by date==== | |||
$ '''find -printf "%TY-%Tm-%Td %TT %p\n" | tail -20 | sort -n''' | $ '''find -printf "%TY-%Tm-%Td %TT %p\n" | tail -20 | sort -n''' | ||
* Have you ever wanted to view a list of all files or subdirectories within a directory in Linux and order them by when they were last changed or modified? Then you have come to the right place! Here we are going to provide and explain some useful commands that when piped together will give us this result, allowing us to recursively list files and directories by date | * Have you ever wanted to view a list of all files or subdirectories within a directory in Linux and order them by when they were last changed or modified? Then you have come to the right place! Here we are going to provide and explain some useful commands that when piped together will give us this result, allowing us to recursively list files and directories by date | ||
* This is one of my favourite commands to use when trying to build a timeline of events, for instance if a server or website has been compromised and you want to see when files have been modified with malicious content. By seeing other files that were modified around the same time you can get a better idea of what took place and when, allowing you to correlate these events with your logs | * This is one of my favourite commands to use when trying to build a timeline of events, for instance if a server or website has been compromised and you want to see when files have been modified with malicious content. By seeing other files that were modified around the same time you can get a better idea of what took place and when, allowing you to correlate these events with your logs | ||
===== | ===== Befehle ===== | ||
* | * Hier sind die einfachen Befehle aneinandergereiht. Führen Sie dies in einem Verzeichnis aus und Sie erhalten eine Liste aller Dateien und Unterverzeichnisse zusammen mit dem Datum, an dem sie zuletzt geändert wurden | ||
* | * Die zuletzt geänderten Inhalte befinden sich am Ende der Liste. Nach dem Ausführen sehen Sie also die neuesten Änderungen zusammen mit den älteren Änderungen, wenn Sie nach oben scrollen | ||
* | * Wenn Sie viele Ausgaben haben, kann es sinnvoll sein, die gesamte Menge in „less“ zu leiten, damit Sie leicht durch die Ausgabe scrollen können | ||
$ '''find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-''' | $ '''find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-''' | ||
* | * Unten sehen Sie ein Beispiel für die Ausgabe dieses vollständigen Befehls. ''' | ||
$ '''find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-''' | $ '''find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-''' | ||
Zeile 134: | Zeile 134: | ||
Tue Sep 1 06:27:43.0000000000 2015 ./1.JPG | Tue Sep 1 06:27:43.0000000000 2015 ./1.JPG | ||
Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg | Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg | ||
Sa., 12. Sep. 12:43:48.0166880221 2015 ./directory | |||
Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg | Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg | ||
Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg | Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg | ||
Mi., 21. Okt. 10:50:16.0672628610 2015 ./index.html | |||
Wie dargestellt, werden die Dateien vom ältesten Änderungsdatum bis zum neuesten sortiert. Sehen wir uns nun an, was jeder Teil tatsächlich für uns tut | |||
====== [http://linux.die.net/man/1/find Find] ====== | |||
Zunächst wird der Befehl „find“ ausgeführt, der uns die Liste aller Dateien und Unterverzeichnisse rekursiv innerhalb des aktuellen Arbeitsverzeichnisses anzeigt, wie durch den „.“ nach dem Befehl „find“ angegeben. Um Ihr aktuelles Arbeitsverzeichnis zu bestätigen, können Sie den Befehl „pwd“ ausführen. Sie können das „.“ durch einen vollständigen Verzeichnispfad ersetzen, um stattdessen alle Dateien und Unterverzeichnisse darin aufzulisten, falls erforderlich. Auf diese Weise müssen Sie sich nicht im Verzeichnis befinden | |||
* | * Das Flag „-printf“ wird verwendet, um die Ausgabe im angegebenen Format zu drucken, in diesem Fall „%T@ %t %p\n“. Das %T@ zeigt die Epochenzeit an, d. h. die Anzahl der Sekunden seit dem 1. Januar 1970, das %t zeigt die letzte Änderungszeit der Datei an, das %p zeigt den Dateinamen an, während \n einfach eine neue Zeile ist, sodass jedes Ergebnis in unserer Ausgabe in einer neuen Zeile angezeigt wird, was das Lesen und Arbeiten erleichtert | ||
* | * Es ist erwähnenswert, dass Sie %t auch durch %c ersetzen können, wodurch stattdessen die letzte Statusänderungszeit der Datei anstelle der Änderungszeit verwendet wird. Dadurch sollten Dinge wie Berechtigungsänderungen angezeigt werden, die die Inhaltsdatei nicht wirklich ändern, sondern die Metadaten | ||
* Die Ausgabe dieses Suchbefehls allein sieht so aus. 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html | |||
* Zu diesem Zeitpunkt wird die Ausgabe nicht in irgendeiner chronologischen Reihenfolge angezeigt. Wir können die Ausgabe wie erwartet sehen, die Dateiepoche, gefolgt vom Datum und der Uhrzeit der letzten Änderung, gefolgt vom Dateinamen | |||
====== [http://linux.die.net/man/1/sort Sort] ====== | |||
Bei dieser Ausgabe haben Sie vielleicht bemerkt, dass keine Reihenfolge angewendet wurde. Dies wird mit dem Sortierbefehl erledigt. Die Option -k gibt eine Startposition an, die in diesem Fall 1 ist, wobei die erste Spalte die Epochenzeit ist | |||
* | * Die Ausgabe mit der Sortierung wird unten angezeigt. Jetzt haben wir die Dateien in derselben Reihenfolge wie die Ausgabe der vollständigen Befehlszeichenfolge, die zuvor nach Sortierung nach Spalte 1, der Epochenzeit, angezeigt wurde. Da die Epochenzeit nur aus Zahlen besteht, verwenden wir auch -n, um eine numerische Sortierung durchzuführen. 1440581104.0000000000 Mi., 26. Aug. 2015, 09:25:04.0000000000 2015 ./images/1.jpg 1441088863.0000000000 Di., 1. Sep. 2015, 06:27:43.00000 00000 2015 ./1.JPG 1442061411.0000000000 Sa Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg 1442061828.1668802210 Sa Sep 1 2 12:43:48.0166880221 2015 ./directory 1444627101.0000000000 Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg 1445156986.0 000000000 So., 18. Okt. 08:29:46.0000000000 2015 ./8.jpg 1445424616.6726286100 Mi., 21. Okt. 10:50:16.0672628610 2015 ./index.html | ||
* Wir können -n in -nr ändern, wodurch die Ausgabe umgekehrt wird, sodass die ältesten geänderten Dateien am Ende der Ausgabe angezeigt werden und nicht die neuesten | |||
====== | ====== [http://linux.die.net/man/1/cut Cut] ====== | ||
Da wir nun unsere sortierte Ausgabe haben, verwenden wir den Befehl cut, um aufzuräumen und eine spezifischere Auswahl auszudrucken. Durch die Angabe eines Trennzeichens mit -d von ' ' finden wir den ersten Leerraum, der nach der Epochenzeit kommt, und schneiden alles danach ab | |||
* An diesem Punkt haben wir nun die vollständige Ausgabe, die alle Dateien nach Datum rekursiv aus dem angegebenen Verzeichnis auflistet. Die Epochenzeit bot eine einfache Möglichkeit, die Sortierung durchzuführen, aber wir müssen sie in der endgültigen Ausgabe nicht wirklich sehen, da sie nicht besonders menschenlesbar ist, sodass sie nach der Sortierung entfernt wurde. | |||
* | |||
===== | ===== Weitere Optionen ===== | ||
Natürlich können Sie jederzeit das viel einfachere „ls -lrt“ innerhalb eines Verzeichnisses verwenden, um alle Dateien im aktuellen Arbeitsverzeichnis von den ältesten bis zu den neuesten anzuzeigen. Dabei werden jedoch die Inhalte der Unterordner nicht berücksichtigt. Selbst wenn wir die rekursive Option verwenden und „ls -lRrt“ verwenden, sehen wir nur die Dateien, die nach den Daten in jedem Verzeichnis geordnet sind, und nicht eine Kombination aller Unterverzeichnisse | |||
* | * Wenn Sie nicht an den Unterverzeichnissen selbst interessiert sind, können Sie auch „-type f“ zum Befehl find hinzufügen, wodurch nur Dateien aufgelistet werden, wie unten dargestellt. find . '''-type f''' -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2- | ||
* Dies listet immer noch Dateien in Unterverzeichnissen auf, es werden lediglich nicht mehr die Namen der Unterverzeichnisse selbst in der Ausgabe angezeigt | |||
* Das Gegenteil kann auch erreicht werden, indem „-type d“ verwendet wird, wodurch nur Verzeichnisse und keine Dateien angezeigt werden. find . '''-type d''' -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2- | |||
====== Quelle | ===== Zusammenfassung ===== | ||
Durch die Kombination einiger relativ einfacher Bash-Befehle in Linux konnten wir erfolgreich alle Dateien und Unterverzeichnisse in einem bestimmten Verzeichnis rekursiv nach ihrem Änderungsdatum in aufsteigender oder absteigender Reihenfolge auflisten. Optional können wir auch festlegen, dass nur Dateien oder Verzeichnisse in der Ausgabe angezeigt werden. | |||
* Dieser Befehl eignet sich hervorragend zum Erstellen einer Zeitachse von Ereignissen, da die chronologische Ausgabe es uns ermöglicht, die Reihenfolge der Dateiänderungen zu sehen, unabhängig davon, wo sich die Datei tatsächlich befindet. | |||
===== Quelle ===== | |||
* https://www.rootusers.com/how-to-search-all-files-by-date-recursively-in-linux/ | * https://www.rootusers.com/how-to-search-all-files-by-date-recursively-in-linux/ | ||
== Siehe auch == | |||
{{Special:PrefixIndex/ | {{Special:PrefixIndex/find}} |
Aktuelle Version vom 23. Dezember 2024, 15:18 Uhr
Ausgabe formatieren
gibt den vollständigen Pfadnamen der getesteten Datei auf die Standardausgabe
- -fprint Ausgabedatei
schreibt den Pfadnamen der getesteten Datei in die Ausgabedatei; wenn die Ausgabedatei nicht existiert, wird sie erzeugt, sonst wird sie erweitert; die Standardausgabe und die Standardfehlerausgabe werden als /dev/stdout und /dev/stderr angesprochen
- -fprint Datei
Gibt die gefunden Dateinamen nicht auf die Standardausgabe (Bildschirm) aus, sondern schreibt diese in die Datei "Datei"
- -print0
gibt den Pfadnamen der getesteten Datei, von einem Nullbyte abgeschlossen, auf die Standardausgabe; auf diese Weise können auch Pfadnamen korrekt weiterverarbeitet werden, die ein Zeilenende enthalten
- -fprint0 Ausgabedatei
schreibt den Namen der getesteten Datei in die Ausgabedatei und schließt die Ausgabe mit einem Nullbyte ab, wie -print0
- -printf
Using the (non-standard) “‑printf” action instead of the default “‑print” is useful to control the output format better than you can with the ls or dir utilities
- You can use find with the ‑printf action to produce output that can easily be parsed by other utilities or imported into spreadsheets or databases
- See the Gnu find man page for the dozens of possibilities with the ‑printf action
- In fact, find with ‑printf is more versatile than ls; it is the preferred tool for forensic examiners even on Windows systems, to list file information.</nowiki>
- For example the following displays non-hidden (no leading dot) files in the current directory only (no subdirectories), with an custom output format: find . -maxdepth 1 -name '[!.]*' -printf 'Name: %16f Size: %6s\n'
“‑maxdepth” is a Gnu extension
- On a modern, POSIX version of find you could use this: find . -path './*' -prune
- On any version of find you can use this more complex (but portable) code: find . ! -name . -prune
- which says to “prune” (don't descend into) any directories except “.”
- Note that “‑maxdepth 1” will include “.” unless you also specify “‑mindepth 1”
- A portable way to include “.” is: find . \( -name . -o -prune \)
- The “\(” and “\)” are just parenthesis used for grouping, and escaped from the shell
- The “‑o” means Boolean OR
- As a system administrator, you can use find to locate suspicious files (e.g., world writable files, files with no valid owner and/or group, Set files, files with unusual permissions, sizes, names, or dates)
- Here's a more complex example (which I saved as a shell script so I can run it often): find / -noleaf -wholename '/proc' -prune \ -o -wholename '/sys' -prune \ -o -wholename '/dev' -prune \ -o -wholename '/windows-C-Drive' -prune \ -o -perm -2 ! -type l ! -type s \ ! \( -type d -perm -1000 \) -print
- This says to seach the whole system, skipping the directories /proc, /sys, /dev, and /windows-C-Drive (presumably a Windows partition on a dual-booted computer)
- The Gnu ‑noleaf option tells find not to assume all remaining mounted filesystems are Unix file systems (you might have a mounted CD for instance)
- The “‑o” is the Boolean OR operator, and “!” is the Boolean NOT operator (applies to the following criteria)
- So these criteria say to locate files that are world writable (“‑perm ‑2”, same as “‑o=w”) and NOT symlinks (“! ‑type l”) and NOT sockets (“! ‑type s”) and NOT directories with the sticky (or text) bit set (“! \( ‑type d ‑perm ‑1000 \)”)
(Symlinks, sockets, and directories with the sticky bit set, are often world-writable and generally not suspicious.)
- -printf Format
gibt für die getestete Datei die Zeichenkette Format auf der Standardausgabe aus; Format kann verschiedene Sonderzeichen und Platzhalter enthalten, die von find bearbeitet werden
\aAlarmton \bRückschritt \cAbbruch der Ausgabe \fSeitenvorschub \nZeilenvorschub \rWagenrücklauf \thorizontaler Tabulator \vvertikaler Tabulator \\der Backslash selbst
- ein Backspace gefolgt von irgendeinem anderen Zeichen wird als normales Zeichen interpretiert und einfach ausgegeben
%% das Prozentzeichen selbst %a die Zeit des letzten Zugriffs auf die Datei, in dem Format der ctime Funktion %A k die Zeit des letzten Zugriffs auf die Datei, in dem von k bestimmte Format; k hat dabei das gleiche Format wie der entsprechende Parameter der strftime Funktion in C
@ Sekunden seit dem 1.1.1970 0 Uhr GMT H Stunde (00 bis 23) I Stunde (01 bis 12) k Stunde (0 bis 23) l Stunde (1 bis 12) M Minute (00 bis 59) p PM oder AM r Zeit, 12 Stunden (hh:mm:ss: AM/PM) S Sekunden (00 bis 61) T Zeit, 24 Stunden (hh:mm:ss) X Zeit (H:M:S) Z Zeitzone, oder nichts a abgekürzter Wochentag A ausgeschriebener Wochentag b abgekürzter Monatsname B ausgeschriebener Monatsname c Datum und Zeit d Tag im Monat D Datum (mm/dd/yy) h das gleiche wie b j der Tag im Jahr m die Zahl des Monats U die Nummer der Woche, Sonntag als erster Wochentag w die Zahl des Wochentags W die Nummer der Woche, Montag als erster Wochentag x Datum (mm/dd/yy) y die letzten beiden Stellen der Jahreszahl Y die Jahreszahl
%b die Dateigröße in 512 Byte Blöcken (aufgerundet) %c das Datum der letzten Statusänderung im Format der C ctime Funktion %Ck das Datum der letzten Statusänderung im Format der BR strftime " Funktion; Parameter wie oben" %d die Höhe der Datei im Verzeichnisbaum; Null bedeutet, dass die Datei Kommandozeilenargument ist
%f der Name der getesteten Datei, ohne Verzeichnisse
%g der Gruppenname der getesteten Datei oder die Kennzahl, wenn die Gruppe nicht eingetragen ist
%G die Gruppenkennzahl
%h die Verzeichnisnamen des Pfadnamen der getesteten Datei
%H das Kommandozeilenargument (Test), mit dem die Datei gefunden wurde
%i die Nummer der Inode der getesteten Datei
%k die aufgerundete Größe der getesteten Datei in Kilobytes
%l das Objekt, auf die ein symbolischer Link zeigt; leer, wenn die getestete Datei kein symbolischer Link ist
%m die Zugriffsrechte als Oktalzahl
%n die Anzahl der harten Links auf die getestete Datei
%p der Pfadname der Datei
%P der Pfadname und das Kommandozeilenargument (Test), mit dem die Datei gefunden wurde
%s die Größe der getesteten Datei in Bytes
%t die Zeit der letzten Änderung, im ctime Format
%Tk die Zeit der letzten Änderung, im strftime Format (siehe oben)
%u der Name des Eigentümers der getesteten Datei oder die Kennzahl, wenn der Benutzer nicht eingetragen ist
%U die Benutzerkennzahl des Eigentümers der getesteten Datei
- -fprintf Ausgabedatei Format
schreibt den Namen der getesteten Datei in die Ausgabedatei und benutzt dabei das Format mit Sonderzeichen wie bei printf
- -prune
Wenn die Datei ein Verzeichnis ist, wird nicht in dieses hinabgestiegen. * wahr, wenn die Option -depth nicht angegeben ist
- falsch, wenn die Option -depth angegeben ist, hat keine Auswirkungen
- Beispiele
Ohne weitere Angaben gibt find die Namen der gefundenen Dateien aus: find /boot/grub/ -name "he*" /boot/grub/hexdump.mod /boot/grub/hello.mod /boot/grub/help.mod
- Wie bereits gesehen kann man mit -ls eine detailliertere Ausgabe erzeugen: find /boot/grub/ -name "he*" -ls 168624 4 -rw-r--r-- 1 root root 3196 Jan 13 17:08 /boot/grub/hexdump.mod 168603 4 -rw-r--r-- 1 root root 1308 Jan 13 17:08 /boot/grub/hello.mod 168623 4 -rw-r--r-- 1 root root 2200 Jan 13 17:08 /boot/grub/help.mod
- Mit -exec und dessen Varianten lassen sich beliebige Programme auf den Fundstellen ausführen
- Die Anzahl der Zeilen in Textdateien findet man mit wc -l DATEI; kombiniert mit find sieht das so aus: </nowiki>
find -name "*.py" -exec wc -l {} \; 10 ./x/abc.py 6 ./x/date-form.py 102 ./x/download.py
- Das Kommando wc -l (Anzahl der Zeilen zählen) wird auf jede gefundene Datei angewandt
- Die geschweiften Klammern werden durch die von find gefundenen Namen ersetzt
- Am Ende muss der ganze Befehl mit einem Semikolon abgeschlossen werden
- Damit das Semikolon nicht von der Shell interpretiert wird, muss man es mit einem Backslash oder Anführungsstrichen maskieren
- Kombination mit -print find tmp -name "a" -exec touch {} \; -print ./tmp/a ./tmp/a/a ./tmp/a/a/a
touch setzt das Datum der Dateien auf den Ausführungszeitpunkt
- Da touch aber nicht den Dateinamen ausgibt sieht man nicht, welche Dateien nun betroffen waren
- Daher schickt man ein -print hinterher
Ausgabe sortieren
$ find -type f -print0 | xargs -0 stat -c "%y %n" | sort -r | head -20
Sort by size
$ find -type f -exec ls -ltu {} \; | sort -k 5 -n
Sort by access time
$ find -type f -exec ls -ltu {} \; | sort -k 6 -M
Search recursively by date
$ find -printf "%TY-%Tm-%Td %TT %p\n" | tail -20 | sort -n
- Have you ever wanted to view a list of all files or subdirectories within a directory in Linux and order them by when they were last changed or modified? Then you have come to the right place! Here we are going to provide and explain some useful commands that when piped together will give us this result, allowing us to recursively list files and directories by date
- This is one of my favourite commands to use when trying to build a timeline of events, for instance if a server or website has been compromised and you want to see when files have been modified with malicious content. By seeing other files that were modified around the same time you can get a better idea of what took place and when, allowing you to correlate these events with your logs
Befehle
- Hier sind die einfachen Befehle aneinandergereiht. Führen Sie dies in einem Verzeichnis aus und Sie erhalten eine Liste aller Dateien und Unterverzeichnisse zusammen mit dem Datum, an dem sie zuletzt geändert wurden
- Die zuletzt geänderten Inhalte befinden sich am Ende der Liste. Nach dem Ausführen sehen Sie also die neuesten Änderungen zusammen mit den älteren Änderungen, wenn Sie nach oben scrollen
- Wenn Sie viele Ausgaben haben, kann es sinnvoll sein, die gesamte Menge in „less“ zu leiten, damit Sie leicht durch die Ausgabe scrollen können
$ find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-
- Unten sehen Sie ein Beispiel für die Ausgabe dieses vollständigen Befehls.
$ find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2- Wed Aug 26 09:25:04.0000000000 2015 ./images/1.jpg Tue Sep 1 06:27:43.0000000000 2015 ./1.JPG Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg Sa., 12. Sep. 12:43:48.0166880221 2015 ./directory Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg Mi., 21. Okt. 10:50:16.0672628610 2015 ./index.html
Wie dargestellt, werden die Dateien vom ältesten Änderungsdatum bis zum neuesten sortiert. Sehen wir uns nun an, was jeder Teil tatsächlich für uns tut
Find
Zunächst wird der Befehl „find“ ausgeführt, der uns die Liste aller Dateien und Unterverzeichnisse rekursiv innerhalb des aktuellen Arbeitsverzeichnisses anzeigt, wie durch den „.“ nach dem Befehl „find“ angegeben. Um Ihr aktuelles Arbeitsverzeichnis zu bestätigen, können Sie den Befehl „pwd“ ausführen. Sie können das „.“ durch einen vollständigen Verzeichnispfad ersetzen, um stattdessen alle Dateien und Unterverzeichnisse darin aufzulisten, falls erforderlich. Auf diese Weise müssen Sie sich nicht im Verzeichnis befinden
- Das Flag „-printf“ wird verwendet, um die Ausgabe im angegebenen Format zu drucken, in diesem Fall „%T@ %t %p\n“. Das %T@ zeigt die Epochenzeit an, d. h. die Anzahl der Sekunden seit dem 1. Januar 1970, das %t zeigt die letzte Änderungszeit der Datei an, das %p zeigt den Dateinamen an, während \n einfach eine neue Zeile ist, sodass jedes Ergebnis in unserer Ausgabe in einer neuen Zeile angezeigt wird, was das Lesen und Arbeiten erleichtert
- Es ist erwähnenswert, dass Sie %t auch durch %c ersetzen können, wodurch stattdessen die letzte Statusänderungszeit der Datei anstelle der Änderungszeit verwendet wird. Dadurch sollten Dinge wie Berechtigungsänderungen angezeigt werden, die die Inhaltsdatei nicht wirklich ändern, sondern die Metadaten
- Die Ausgabe dieses Suchbefehls allein sieht so aus. 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
- Zu diesem Zeitpunkt wird die Ausgabe nicht in irgendeiner chronologischen Reihenfolge angezeigt. Wir können die Ausgabe wie erwartet sehen, die Dateiepoche, gefolgt vom Datum und der Uhrzeit der letzten Änderung, gefolgt vom Dateinamen
Sort
Bei dieser Ausgabe haben Sie vielleicht bemerkt, dass keine Reihenfolge angewendet wurde. Dies wird mit dem Sortierbefehl erledigt. Die Option -k gibt eine Startposition an, die in diesem Fall 1 ist, wobei die erste Spalte die Epochenzeit ist
- Die Ausgabe mit der Sortierung wird unten angezeigt. Jetzt haben wir die Dateien in derselben Reihenfolge wie die Ausgabe der vollständigen Befehlszeichenfolge, die zuvor nach Sortierung nach Spalte 1, der Epochenzeit, angezeigt wurde. Da die Epochenzeit nur aus Zahlen besteht, verwenden wir auch -n, um eine numerische Sortierung durchzuführen. 1440581104.0000000000 Mi., 26. Aug. 2015, 09:25:04.0000000000 2015 ./images/1.jpg 1441088863.0000000000 Di., 1. Sep. 2015, 06:27:43.00000 00000 2015 ./1.JPG 1442061411.0000000000 Sa Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg 1442061828.1668802210 Sa Sep 1 2 12:43:48.0166880221 2015 ./directory 1444627101.0000000000 Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg 1445156986.0 000000000 So., 18. Okt. 08:29:46.0000000000 2015 ./8.jpg 1445424616.6726286100 Mi., 21. Okt. 10:50:16.0672628610 2015 ./index.html
- Wir können -n in -nr ändern, wodurch die Ausgabe umgekehrt wird, sodass die ältesten geänderten Dateien am Ende der Ausgabe angezeigt werden und nicht die neuesten
Cut
Da wir nun unsere sortierte Ausgabe haben, verwenden wir den Befehl cut, um aufzuräumen und eine spezifischere Auswahl auszudrucken. Durch die Angabe eines Trennzeichens mit -d von ' ' finden wir den ersten Leerraum, der nach der Epochenzeit kommt, und schneiden alles danach ab
- An diesem Punkt haben wir nun die vollständige Ausgabe, die alle Dateien nach Datum rekursiv aus dem angegebenen Verzeichnis auflistet. Die Epochenzeit bot eine einfache Möglichkeit, die Sortierung durchzuführen, aber wir müssen sie in der endgültigen Ausgabe nicht wirklich sehen, da sie nicht besonders menschenlesbar ist, sodass sie nach der Sortierung entfernt wurde.
Weitere Optionen
Natürlich können Sie jederzeit das viel einfachere „ls -lrt“ innerhalb eines Verzeichnisses verwenden, um alle Dateien im aktuellen Arbeitsverzeichnis von den ältesten bis zu den neuesten anzuzeigen. Dabei werden jedoch die Inhalte der Unterordner nicht berücksichtigt. Selbst wenn wir die rekursive Option verwenden und „ls -lRrt“ verwenden, sehen wir nur die Dateien, die nach den Daten in jedem Verzeichnis geordnet sind, und nicht eine Kombination aller Unterverzeichnisse
- Wenn Sie nicht an den Unterverzeichnissen selbst interessiert sind, können Sie auch „-type f“ zum Befehl find hinzufügen, wodurch nur Dateien aufgelistet werden, wie unten dargestellt. find . -type f -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2-
- Dies listet immer noch Dateien in Unterverzeichnissen auf, es werden lediglich nicht mehr die Namen der Unterverzeichnisse selbst in der Ausgabe angezeigt
- Das Gegenteil kann auch erreicht werden, indem „-type d“ verwendet wird, wodurch nur Verzeichnisse und keine Dateien angezeigt werden. find . -type d -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d ' ' -f2-
Zusammenfassung
Durch die Kombination einiger relativ einfacher Bash-Befehle in Linux konnten wir erfolgreich alle Dateien und Unterverzeichnisse in einem bestimmten Verzeichnis rekursiv nach ihrem Änderungsdatum in aufsteigender oder absteigender Reihenfolge auflisten. Optional können wir auch festlegen, dass nur Dateien oder Verzeichnisse in der Ausgabe angezeigt werden.
- Dieser Befehl eignet sich hervorragend zum Erstellen einer Zeitachse von Ereignissen, da die chronologische Ausgabe es uns ermöglicht, die Reihenfolge der Dateiänderungen zu sehen, unabhängig davon, wo sich die Datei tatsächlich befindet.