Find/Ausgabe: Unterschied zwischen den Versionen
Zeile 156: | Zeile 156: | ||
* At this point we now have the complete output which lists all files by date recursively from the specified directory. The epoch time provided an easy way to perform the sort, but we don’t really need to see that in the final output as it isn’t particularly human readable so it’s been removed after the sort | * At this point we now have the complete output which lists all files by date recursively from the specified directory. The epoch time provided an easy way to perform the sort, but we don’t really need to see that in the final output as it isn’t particularly human readable so it’s been removed after the sort | ||
===== | ===== 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 ===== | ===== Zusammenfassung ===== |
Version vom 23. Dezember 2024, 15:09 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
The Commands
- So here are the simple commands piped together, run this within a directory and you will be provided with a list of all files and subdirectories along with the date they were last modified
- The most recently changed contents will be at the bottom of the list, so after running it you’ll see the most recent changes with the older changes as you scroll up
- If you have a lot of output piping the whole lot into ‘less’ may be a good idea so that you can easily scroll through
$ find . -printf '%T@ %t %p\n' | sort -k 1 -n | cut -d' ' -f2-
- Below is an example output from running this full command.
$ 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 Sat Sep 12 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 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
- As shown we can see the files sorted from oldest date and time modified to newest. Now let’s break down what each part is actually doing for us
Find
First off the find command is run which finds us the list of all files and subdirectories recursively within the current working directory, as specified by the “.” after the find command. To confirm your current working directory you can run the “pwd” command. You can change the “.” to a full directory path instead to list all files and subdirectories in there instead if required, this way you don’t have to be in the directory
- The “-printf” flag is used to print the output in the format specified, in this case this is ‘%T@ %t %p\n’. The %T@ displays the epoch time, that is the amount of seconds since the 1st of January 1970, the %t shows the files last modification time, the %p displays the files name while \n is simply a new line so that each result in our output shows up on a new line which makes it easier to read and work with
- It is worth noting that you could also replace %t with %c, which will instead use the files last status change time rather than the modification time. This should show things such as permission changes which don’t actually modify the contents file but change the metadata
- The output of this find command alone looks like this. 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
- At this stage the output does not display in any sort of chronological order. We can see the output displayed as expected, the files epoch time followed by the last modification date and time, followed by the file name
Sort
Now with this output you may have noticed that there is no order applied, this is taken care of with the sort command. The -k flag specifies a start position which in this case is 1, the first column being the epoch time
- The output with the sort is shown below, now we have the files in the same order as the output of the full command string shown previously after sorting by column 1, the epoch time. As the epoch time is all numbers, we also use -n to perform a numerical based sort. 1440581104.0000000000 Wed Aug 26 09:25:04.0000000000 2015 ./images/1.jpg 1441088863.0000000000 Tue Sep 1 06:27:43.0000000000 2015 ./1.JPG 1442061411.0000000000 Sat Sep 12 12:36:51.0000000000 2015 ./directory/6.jpg 1442061828.1668802210 Sat Sep 12 12:43:48.0166880221 2015 ./directory 1444627101.0000000000 Mon Oct 12 05:18:21.0000000000 2015 ./images/7.jpg 1445156986.0000000000 Sun Oct 18 08:29:46.0000000000 2015 ./8.jpg 1445424616.6726286100 Wed Oct 21 10:50:16.0672628610 2015 ./index.html
- We can change -n to -nr which will reverse the output, resulting in the oldest modified files showing at the bottom of the output, rather than the newest
Cut
Now that we have our sorted output we use the cut command to tidy up and print out a more specific selection. By specifying a delimiter with -d of ‘ ‘ we find the first white space which comes after the epoch time and cut everything afterwards
- At this point we now have the complete output which lists all files by date recursively from the specified directory. The epoch time provided an easy way to perform the sort, but we don’t really need to see that in the final output as it isn’t particularly human readable so it’s been removed after the sort
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.