Suche in Datenformaten (Teil 2)

Aus LinuxUser 07/2012

Suche in Datenformaten (Teil 2)

© Abcdz2000, sxc.hu

Durchgekämmt

Wer Grep kennt, der findet Alles. Wer obendrein die Spezialvarianten beherrscht, findet das Gesuchte auch an sonst unzugänglichen Orten.

Grep besticht mit dem Prinzip, Textdateien und Datenströme schnell nach Mustern zu durchsuchen. Daher gibt es ein Vielzahl von Varianten, deren Fokus auf Datei- oder Textformaten liegt, die das Original nicht so leicht verdaut. Die Suche nach Mustern in Prozesslisten oder systemrelevanten Dateien verläuft oft nach dem gleichen Prinzip, ebenso wie jene in speziellen Formaten wie E-Mail-Ordnern oder sogar Versionskontrollsystemen.

TIPP

Ein erster Teil des Workshops hat sich bereits mit speziellen Anwendungsformaten beschäftigt [1]. Er ergänzt diesen Workshop, Sie können beide Beiträge aber unabhängig voneinander lesen.

Prozessliste

Zu den Aufgaben eines Administrators gehört es, die ihm anvertrauten Rechner bestmöglich zu betreuen. Das beinhaltet das Beobachten der Systemlast und der laufenden Prozesse. Für Einzelplatzsysteme genügen meist die Werkzeuge Ps, Pstree, Pidof, Pgrep [2] und Htop [3]. Beim permanenten Monitoring ganzer Rechnerverbünde (etwa im Rechenzentrum) dagegen spielen häufig die webbasierten Werkzeuge Munin [4], Nagios [5], Cacti [6] und Icinga [7] ihre Stärken aus.

Trotz aller Aufmerksamkeit kommt es immer wieder vor, dass ein Programm oder Prozess versucht, die CPU vollständig für sich zu vereinnahmen, und damit andere Prozesse blockiert. Um solche Störenfriede zu bändigen, benötigen Sie die entsprechende Nummer des Prozesses (Prozess-ID). Hier hilft Pgrep weiter: Es durchsucht die Liste der Prozesse anhand eines Musters und liefert die entsprechenden IDs zurück. Dabei haben Sie die Möglichkeit, das Muster als regulären Ausdruck [8] zu formulieren.

Der Ursprung von Pgrep geht auf Solaris 7 zurück, inzwischen gibt es das Tool auch für Linux und OpenBSD [9]. Unter Debian/Ubuntu gehört es zum Paket Procps [10]. Das Programm entspricht in der Grundfunktionalität der folgenden Kombination aus Kommandos:

$ ps ax | grep Prozessname | grep -v grep | awk '{print $1}'

Im einfachsten Fall übergeben Sie Pgrep beim Aufruf als Parameter den Namen des Programms, nach dem Sie die Liste durchsuchen möchten. Als Rückgabe erhalten Sie die IDs aller Einträge, auf die das Muster passt. Die Option -l ergänzt die Ausgabe um den Programmnamen (Listing 1).

Listing 1

$ pgrep ssh
1746
5660
6004
$ pgrep -l ssh
1746 sshd
5660 ssh-agent
6004 ssh

Pgrep bietet die Möglichkeit, die Ausgabe nach den jeweiligen Nutzern zu filtern. Mit der Option -u thomas legen Sie fest, dass das Tool nur die Prozesse ausgibt, die dem Benutzer thomas gehören. Mehrere Benutzernamen trennen Sie durch Kommata (-u thomas,helmut). Damit sehen Sie die Prozesse, die entweder dem Benutzer thomas oder helmut gehören. Listing 2 zeigt die Informationen zum Netzwerkmonitor Wicd [11], dessen Prozesse dem Benutzer root gehören.

Listing 2

$ pgrep -lu root wicd
1811 wicd
1836 wicd-monitor

Auch der Schalter -v erweist sich oft als hilfreich: Damit invertieren Sie den Filter. So sehen Sie alle Prozesse, die nicht dem Suchkriterium entsprechen. Der Aufruf pgrep -v -u thomas zeigt alle Prozesse an, die nicht zum Benutzer thomas gehören. Interessiert Sie lediglich die Anzahl der Prozesse, hilft die Option -c (“count”) weiter.

Netzwerkpakete

Was Pgrep bei der Suche in der Prozessliste bietet, das leistet Ngrep [12] für den Datenverkehr im Netzwerk. Die Software durchsucht den Traffic und filtert jene Verbindungen und Pakete heraus, auf die das angegebene Suchmuster passt. Herausfiltern bedeutet hier nicht das Blockieren im Datenstrom wie bei einer Firewall: Das Tool teilt lediglich mit, dass ein solches Paket im Datenstrom aufgetaucht ist.

Ngrep versteht sich auf TCP-, UDP- und ICMP-Verbindungen über Ethernet, Point-to-Point Protocol (PPP), Serial Line Internet Protocol (SLIP) und Fiber Distributed Data Interface (FDDI). Eine inhaltsbezogene Suche funktioniert nur sinnvoll bei den verschiedenen Klartextprotokollen, wie SMTP, HTTP, FTP und POP3. Beim Übertragen verschlüsselter Daten erhalten Sie dagegen keine geeigneten Treffer. Als Suchmuster kommt bei Bedarf ein regulärer Ausdruck zum Einsatz. Die Tabelle “Ngrep-Beispiele” zeigt einige kommentierte Beispiele für den Einsatz von Ngrep. Weitere Details und Optionen bietet die umfangreiche Manpage.

Ngrep-Beispiele

Kommando Kommentar
ngrep -q GET GET-Requests ermitteln.
ngrep 'USER|PASS' src host 192.168.0.20 and src tcp port 21 Accountdaten bei FTP-Zugriffen ermitteln. Das Kommando sucht im Datenstrom nach den Zeichenketten USER oder PASS. Dabei betrachtet es alle Pakete, die vom Host 192.168.0.20 kommen und Quell- oder Zielport 21 (FTP) besitzen.
ngrep SSH port 22 Alle Verbindungen zum SSH-Port 22 anzeigen.
ngrep -iq user-agent tcp port 80 Browsertyp anzeigen, mit dem ein Benutzer auf einen Webserver zugreift. Die Option -i ignoriert Groß- und Kleinschreibung, über q erhalten Sie nur die Kopfzeilen und den Inhalt der Pakete. Mit der Angabe tcp port 80 lauscht Ngrep auf dem Port 80, beschränkt sich dabei aber auf TCP-Verbindungen.

Ngrep kombiniert die Stärken von Grep mit einem Werkzeug zur Fehlersuche im Netzwerk und dem Paketscannen. Alternativen zu Ngrep finden Sie zum Beispiel in Tcpdump [13], Wireshark [14] und dessen Kommandozeilenversion Tshark sowie dem Nmap-Frontend Zenmap [15].

Während Tcpdump und Tshark ebenfalls für die Kommandozeile gedacht sind, benötigen Wireshark und Zenmap das X-Window-System. Alle Werkzeuge inklusive Ngrep haben einen großen Funktionsumfang und gehören zum Standardwerkzeugkasten eines Administrators.

E-Mails

Grep eignet sich zwar gut zum zeilenweisen Durchforsten von Dateien, aber bei im gängigen Mbox-Format vorliegenden E-Mail-Ordnern versagt es kläglich: Es findet zwar Treffer, gibt aber nicht aus, in welcher E-Mail, sondern höchstens in welchen Ordnern.

Dieses Problem lösen sowohl das in C geschriebene Mboxgrep [16] wie das in Perl geschriebene Grepmail [17]. Beide suchen in einem E-Mail-Ordner nach Nachrichten, die das Suchmuster enthalten, und geben dann die gesamte E-Mail, in der das Suchmuster vorkommt, zurück. Das hat den Vorteil, dass sich die Ausgabe der beiden Programme wieder als Eingabe für eine weitere Instanz eignet.

Das Beispiel in Listing 3 sucht zunächst alle E-Mails heraus, in denen die Zeichenkette tmpreaper vorkommt, und filtert im zweiten Schritt diejenigen heraus, die zusätzlich die Zeichenkette localhost enthalten.

Listing 3

# mboxgrep tmpreaper /var/mail/root | mboxgrep localhost

Das Programm verfügt über die von Grep her vertrauten Optionen -i für eine Suche unabhängig von Groß- und Kleinschreibung sowie -v für die inverse Suche, also die Suche nach allen E-Mails, die das Muster nicht enthalten.

Da Grepmail in Perl geschrieben ist, nutzt es dessen reguläre Ausdrücke zur Suche – und nur diese. Mboxgrep dagegen bietet fast alle Suchmuster-Formate an, die Sie von Grep her kennen: Einfache reguläre Ausdrücke (Option -G), reguläre Ausdrücke nach Posix (Option -E, Vorgabe) und Perl-kompatible reguläre Ausdrücke (PCRE, Option -P). Nur die Suche nach der exakt angegebenen Zeichenkette fehlt.

Beide Programme unterstützen das Mbox-Format – sowohl als unkomprimierte Textdateien als auch in mit Gzip und Bzip2 komprimierter Form. Bei diesem Format liegen alle E-Mails in einer Datei. Mboxgrep unterstützt zusätzlich die verzeichnisbasierten Mail-Ordner-Formate MH, NNMH, NNML und Maildir. Im Notfall ließe sich darin allerdings auch etwas mit dem normalen Grep erreichen.

Beide Tools zählen auf Wunsch die Anzahl der E-Mails, allerdings mit unterschiedlichen Optionen und leicht unterschiedlichen Ausgaben. Auch in diesem Fall arbeitet Mboxgrep näher am originalen Grep: Dessen Option -c (wie bei Grep als Langoption --count) gibt den Ordnernamen nur dann mit aus, wenn Sie mehr als einen E-Mail-Ordner auf der Kommandozeile zum Durchsuchen angegeben haben. Die Option -r (“report”) von Grepmail gibt stets den Ordnernamen mit aus.

Möchten Sie entweder nur in den Kopfzeilen oder nur im Inhalt der E-Mail suchen, unterscheiden sich die beiden Tools leicht: Während sich bei Mboxgrep die beiden Optionen -H und -B auf Kopfzeilen (“header”) und Inhalt (“body”) beziehen, sind es bei Grepmail die Optionen -h und -b.

Im Gegensatz dazu veranlassen die Optionen -H und -B Grepmail dazu, nur Kopfzeilen oder nur den Inhalt (plus eine minimale Anzahl an Kopfzeilen) auszugeben. Mehrfach vorkommende, identische E-Mails unterdrücken Sie bei Grepmail mit der Option -u (“unique”), bei Mboxgrep durch die Option -nd bzw. --no-duplicates (Langform).

Grepmail verfügt zusätzlich über die Möglichkeit, die Namen des E-Mail-Ordners, in dem es die Nachricht gefunden hat, als Kopfzeile X-Mailfolder in die ausgegebenen E-Mails einzubauen, Zeilennummern anzugeben, nur Nachrichten bestimmter Größe herauszusuchen, Signaturen bei der Suche zu ignorieren oder nur in bestimmten Kopfzeilen zu suchen. Dafür glänzt Mboxgrep mit der (nicht ganz ungefährlichen) Möglichkeit, alle E-Mails, die das Suchmuster enthalten, direkt aus dem angegebenen E-Mail-Ordner zu löschen.

Mit Gtkgrepmail existiert ein grafisches Frontend für Grepmail [18]. Es basiert jedoch immer noch auf den Bibliotheken von Gnome 1.x, die in nahezu keiner Linux-Distribution mehr bereit stehen. Vermutlich deshalb gibt es auch in kaum einer Distribution ein passendes Paket. Die Debian-Entwickler entfernten Gtkgrepmail bereits 2008 aus dem genannten Grund [19].

Kurz gesagt: Mboxgrep und Grepmail schenken sich nicht viel. Mboxgrep gleicht vom Bedienkonzept stärker dem originalen Grep, versteht sich auf verzeichnisbasierte Ordnerformate und arbeitet aufgrund der Implementation in C schneller. Dafür dürfen Sie bei Grepmail genauer spezifizieren, wonach sie suchen und welche Bestandteile der E-Mails auf der Ausgabe erscheinen sollen. Die nachfolgenden Beispiele demonstrieren die Mächtigkeit der beiden Werkzeuge.

Listing 4 zeigt einen Aufruf von Grepmail, mit dem Sie alle Nachrichten finden, in denen die Zeichenkette HTML vorkommt. Die Option -m ergänzt die Kopfzeile der gefundenen E-Mail um den Namen des Ordners. Dabei durchsucht das Programm alle E-Mail-Ordner, auf die das Muster mbox* passt.

Listing 4

$ grepmail -m HTML mbox*
From abe@deuxchevaux.org Wed Mar 14 00:23:42 2012
From: Axel Beckert <abe@deuxchevaux.org>
To: Frank Hofmann <frank.hofmann@efho.de>
Subject: Beispielmail 1
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Date: Wed, 14 Mar 2012 00:23:42 +0100
Status: RO
X-Mailfolder: mbox1
Hallo Frank,
diese Mail ist nicht in HTML geschrieben.
              Gruss, Axel
--
/~\  Plain Text Ribbon Campaign
\ /  Say No to HTML in E-Mail and News
 X   See http://www.asciiribbon.org/
/ \  I love long mails: http://email.is-not-s.ms/
From abe@deuxchevaux.org Wed Mar 14 00:42:23 2012
From: Axel Beckert <abe@deuxchevaux.org>
To: Frank Hofmann <frank.hofmann@efho.de>
Subject: Beispielmail 2
MIME-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Date: Wed, 14 Mar 2012 00:42:23 +0100
Status: RO
X-Mailfolder: mbox2
Hallo Frank,
meine Homepage findest Du unter http://noone.org/abe/
              Gruss, Axel
--
/~\  Plain Text Ribbon Campaign
\ /  Say No to HTML in E-Mail and News
 X   See http://www.asciiribbon.org/
/ \  I love long mails: http://email.is-not-s.ms/

Listing 5 zeigt eine Variante: Wieder gibt das Programm alle E-Mails aus, in denen die Zeichenkette HTML vorkommt – diesmal spart es aber die aus, die den String nur in der Signatur tragen (Option -S). Im Vergleich zu Listing 4 fehlt hier also die zweite E-Mail. Die Ausgabe enthält nur minimal notwendige Kopfzeilen (Option -B) und Zeilennummern (Option -n).

Listing 5

$ grepmail -n -S -B HTML mbox*
mbox1:1:From abe@deuxchevaux.org Wed Mar 14 00:23:42 2012
mbox1:2:From: Axel Beckert <abe@deuxchevaux.org>
mbox1:4:Subject: Beispielmail 1
mbox1:8:Date: Wed, 14 Mar 2012 00:23:43 +0100
mbox1:12:
mbox1:13:Hallo Frank,
mbox1:14:
mbox1:15:diese Mail ist nicht in HTML geschrieben.
mbox1:16:
mbox1:17:               Gruss, Axel
mbox1:18:--
mbox1:19:/~\  Plain Text Ribbon Campaign                   | Axel Beckert
mbox1:20:\ /  Say No to HTML in E-Mail and News            | abe@deuxchevaux.org  (Mail)
mbox1:21: X   See http://www.asciiribbon.org/              | abe@noone.org (Mail+Jabber)
mbox1:22:/ \  I love long mails: http://email.is-not-s.ms/ | http://noone.org/abe/ (Web)
mbox1:23:

Um die E-Mails zu zählen, in denen die Zeichenkette Gruss vorkommt (Option -c bei Mboxgrep, Option -r bei Grepmail), verwenden Sie einen Aufruf wie in Listing 6. Die Suche findet über alle Dateien statt, auf die das Muster mbox* passt.

Listing 6

$ mboxgrep -c Gruss mbox*
mbox1:1
mbox2:1
$ grepmail -r Gruss mbox*
mbox1: 1
mbox2: 1

Versionskontrolle

Noch etwas komplizierter als in einer Mailbox gestaltet sich die Suche im Quellcode-Baum eines Versionskontrollsystems (VCS). Suchen Sie mit Grep einfach im Dateisystem, erhalten Sie möglicherweise nicht alle Treffer, weil Sie einige Dateien gerade nicht ausgebucht haben. Zusätzliche Einträge aus Steuerdateien erschweren das Lesen des Ergebnisses ebenfalls.

Das mächtiges, verteiltes Versionskontrollsystem Git verfügt über ein Unterkommando, das ebenfalls grep heißt. Es ermöglicht, in Daten zu suchen, ohne diese aus dem VCS auszuchecken oder Treffer in den Metadaten zu landen. Der Entwickler Julius Plenz schreibt dazu in seinem Blog, dass git grep außerdem deutlich schneller arbeitet als das reguläre Grep [21]. Die Tabelle “Beispiele zu git Grep” zeigt einige kommentierte Aufrufe. Weitere ausführlichere Beispiele und Kommentare zu git grep finden Sie in dem von Scott Chacon betreuten Git-Community-Buch [22].

Beispiele zu <C>git grep<C>

Kommando Kommentar
git grep Muster Standardaufruf
git grep -n Muster Zeilennummer ausgeben
git grep --name-only Muster nur Dateiname ausgeben
git grep -e '#define' --and -e SORT_DIRENT Suchmuster kombinieren

Fazit

Die hier besprochenen Programme decken allerdings nur eine kleinere Auswahl ab. Es blieben beispielsweise Grepcidr und die Grep-Alternative Ack unberücksichtigt, ebenso das Durchsuchen der Paketinformationen mit Grep-dcontrol. 

Infos

[1] Suche in Datenformaten (Teil 1): Axel Beckert, Frank Hofmann, “Mit Struktur” , LU 06/2012, S. 82, https://www.linux-community.de/25404

[2] Wikipedia-Eintrag zu Pgrep: http://de.wikipedia.org/wiki/Pgrep

[3] Htop: http://htop.sourceforge.net

[4] Munin: http://munin-monitoring.org

[5] Nagios: http://www.nagios.org

[6] Cacti: http://www.cacti.net

[7] Icinga: https://www.icinga.org

[8] Reguläre Ausdrücke: Frank Hofmann, “Schnipseljagd”, LU 09/2011, S. 84, https://www.linux-community.de/24091

[9] Pgrep: http://linux.die.net/man/1/pgrep

[10] Debian-Paket procps: http://packages.debian.org/squeeze/procps

[11] Wicd: https://launchpad.net/wicd

[12] Ngrep: http://ngrep.sourceforge.net

[13] Tcpdump: http://www.tcpdump.org

[14] Wireshark: http://www.wireshark.org

[15] Zenmap, http://nmap.org/zenmap/

[16] Mboxgrep: http://www.mboxgrep.org

[17] Grepmail: http://grepmail.sourceforge.net

[18] Gtkgrepmail, http://www.malcolm.id.au/files/software/unix/gtkgrepmail/

[19] Gtkgrepmail aus Debian entfernt: http://bugs.debian.org/460786

[20] Mailordner durchsuchern: Andreas Kneib, “Hide & Seek”, LU 09/2003, S. 61, https://www.linux-community.de/4476

[21] Git Grep: http://blog.plenz.com/2011-12/git-grep.html

[22] Git-Handbuch von Scott Chacon: http://book.git-scm.com/4_finding_with_git_grep.html

[] Die Autoren bedanken sich bei Thomas Osterried, Julius Plenz und Michael Stehmann für deren kritische Anmerkungen, Kommentare und Ergänzungen im Vorfeld dieses Artikels.

Der Autor

Axel Beckert (http://noone.org/abe/) hat Informatik an der Universität des Saarlandes in Saarbrücken studiert. Er arbeitet als Systemadministrator an der ETH Zürich am Departement für Physik. Nebenher ist er ehrenamtlich beim Debian-Projekt, in der Linux User Group Switzerland (LUGS), beim Hackerfunk (Radiosendung und Podcast) sowie weiteren Open-Source-Projekten aktiv.

Frank Hofmann (http://www.efho.de) hat Informatik an der Technischen Universität Chemnitz studiert. Derzeit arbeitet er in Berlin im Büro 2.0, einem Open-Source Experten-Netzwerk, als Dienstleister mit Spezialisierung auf Druck und Satz. Er ist Mitgründer des Schulungsunternehmens Wizards of FOSS. Seit 2008 koordiniert er das Regionaltreffen der Linux User Groups aus der Region Berlin-Brandenburg.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDF
LinuxUser 07/2012 KAUFEN
EINZELNE AUSGABE
ABONNEMENTS
TABLET & SMARTPHONE APPS
E-Mail Benachrichtigung
Benachrichtige mich zu:

Hinweis: Dieser Artikel ist älter als ein Jahr, enthaltene Informationen sind möglicherweise veraltet.

0 Kommentare
Älteste
Neuste Beste Bewertung
Inline Feedbacks
Alle Kommentare anzeigen
Nach oben