Suchbefehle in der Linux-Konsole (I)

Ich wage mich jetzt einmal an das Thema suchen in der Linux-Shell. Das Thema ist letztlich ein Fass ohne Boden da alleine der Befehl find sehr mächtig ist und man durch die möglichen Optionen schier erschlagen wird. find ist sicher der Befehl der am bekanntesten ist aber es gibt eine ganze Reihe nützliche und spezialisierterer aber deutlich unbekanntere Befehle die einem das Leben erleichtern wenn man etwas im Dateisystem sucht. Der Befehl find wird hier nicht behandelt sondern wird separat im zweiten Teil dieser Serie behandelt. Die hier behandelten Befehle sind:

  • grep
  • which
  • whereis
  • apropos
  • whatis
  • locate

grep

grep gehört sicher noch zu den bekannten Befehlen und wird oft eingesetzt um innerhalb von Dateien oder in Ausgaben auf stdout und stderr etwas zu suchen:

# grep root /etc/passwd
root:x:0:0:root:/root:/bin/bash

grep wird hier benutzt um die Datei /etc/passwd, also die Datei mit den Benutzerkonten, nach dem administrativen Benutzer root zu durchsuchen und die Ergebniszeile auf stdout auszugeben. Eine verbreitete Unsitte wäre die Ausführung als cat /etc/passwd | grep root da es unter die Abteilung „useless use of pipe“ fällt da grep das selber kann. Nun mag man sich denken, dass ist ja trivial und eigentlich ist das auch Teil des Tagesgeschäft auf der Shell. Nun stellen wir uns folgenden Fall vor. Gesucht wird eine Konfigurationsdatei die eine Zeile enthält von der wir uns erinnern können, dass sie permitroot enthält. Konfigurationsdateien befinden sich laut FHS im Verzeichnis /etc und damit haben wir bereits unseren gesuchten Suchbefehl:

# grep -ri permitroot /etc/
/etc/ssh/sshd_config:#PermitRootLogin prohibit-password
/etc/ssh/sshd_config:PermitRootLogin no
/etc/ssh/sshd_config:# the setting of "PermitRootLogin without-password".

Hier wird nach dem String permitroot im Verzeichnis /etc gesucht und die Option -r steht für rekursives Suchen und die Option -i für die case-unsensitive Suche. Das Ergebnis der Suche führt zur Datei /etc/ssh/sshd_config was die Konfigurationsdatei des ssh-Daemons ist.

grep beherrscht die regulären Ausdrücke und je nach Variante (egrep, fgrep, rgrep) mehr oder minder komplex und daher können wir auch nach Textmustern suchen. Die obige Suche mit regulären Ausdrücken könnt z.B. grep -r [pP]ermit[rR]oot /etc/ lauten. Hier wissen wir nicht ob Permit bzw. root in Groß- oder Kleinbuchstaben anfängt und führt zum gleichen Ergebnis wie oben. grep bietet eine Vielzahl von Optionen und dazu noch diese regulären Ausdrücke und eine genauere Beschreibung würde diesen Rahmen sprengen.

which

which ist ein kleines aber nützliches Programm auf der Suche nach ausführbaren Dateien. Angenommen wir möchten wissen welches Binary bei der Eingabe von ls aufgerufen wird dann ist which das Hilfsmittel der Wahl:

# which ls
/bin/ls

Der Aufruf von which führt uns direkt zum Pfad der die ausführbare Datei ls enthält. Man kann which auch gut mit anderen Befehlen kombinieren:

# file $(which ls)
/bin/ls: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=a65f86cd6394e8f583c14d786d13b3bcbe051b87, stripped

which gibt hier den Pfad zu ls zurück und file bestimmt den Dateityp der wie erwartet eine binäre Datei ist. Aber auch bei Scripten die im Suchpfad stehen und wie Programme aufgerufen werden wird der richtige Wert zurück gegeben:

# file $(which fail2ban-client)
/usr/bin/fail2ban-client: Python script, ASCII text executable

Die Optionen von which sind recht überschaubar und wenig interessant.

whereis

Teilweise überschneidend zu which ist der Befehl whereis. Dieser liefert ebenfalls die ausführbare Datei mit dem Pfad zurück. Jedoch sucht whereis über eine ganze Reihe an Pfaden nach dem Ergebnis. Die Pfade in denen whereis sucht kann man sich mit whereis -l anzeigen lassen. Dadurch das whereis auch andere Pfade als die der Binarys durchsucht werden auch Handbuchseiten und Quellcodes im Dateisystem gefunden.

$ whereis pwd
pwd: /bin/pwd /usr/include/pwd.h /usr/share/man/man1/pwd.1.gz

Hier findet whereis für pwd das Programm, einen c-Header und die Handbuchseite. Mit den Optionen -p und -m kann die Suche auf Binary und Handbuchseiten eingeschränkt werden.

$ whereis -b pwd
pwd: /bin/pwd /usr/include/pwd.h
$ whereis -m pwd
pwd: /usr/share/man/man1/pwd.1.gz

Es gibt sicher bessere Suchbefehle und dieser ist etwas den man im Hinterkopf haben kann.

apropos und whatis

Bei Debian-Systemen ist apropos ein symbolischer Link auf whatis und daher auch die gemeinsame Behandlung. Beide Befehle haben trotz des identischen ausgeführten Programm unterschiedliche Ausgaben. Beide Funktionen sind spezialisiert auf Handbuchseiten. Apropos durchsucht alle Seiten nach einem Stichwort und whatis versucht die eine Seite zu finden. Am Beispiel des gcc sieht das so aus:

$ apropos gcc
c89-gcc (1) - ANSI (1989) C compiler
c99-gcc (1) - ANSI (1999) C compiler
gcc (1) - GNU project C and C++ compiler
gcc-6 (1) - GNU project C and C++ compiler
gcc-ar (1) - a wrapper around ar adding the --plugin option
gcc-ar-6 (1) - a wrapper around ar adding the --plugin option
gcc-ar-8 (1) - a wrapper around ar adding the --plugin option
gcc-nm (1) - a wrapper around nm adding the --plugin option
gcc-nm-6 (1) - a wrapper around nm adding the --plugin option
gcc-nm-8 (1) - a wrapper around nm adding the --plugin option
gcc-ranlib (1) - a wrapper around ranlib adding the --plugin option
gcc-ranlib-6 (1) - a wrapper around ranlib adding the --plugin option
gcc-ranlib-8 (1) - a wrapper around ranlib adding the --plugin option
x86_64-linux-gnu-gcc-ar (1) - a wrapper around ar adding the --plugin option
x86_64-linux-gnu-gcc-ar-6 (1) - a wrapper around ar adding the --plugin option
x86_64-linux-gnu-gcc-ar-8 (1) - a wrapper around ar adding the --plugin option
x86_64-linux-gnu-gcc-nm (1) - a wrapper around nm adding the --plugin option
x86_64-linux-gnu-gcc-nm-6 (1) - a wrapper around nm adding the --plugin option
x86_64-linux-gnu-gcc-nm-8 (1) - a wrapper around nm adding the --plugin option
x86_64-linux-gnu-gcc-ranlib (1) - a wrapper around ranlib adding the --plugin option
x86_64-linux-gnu-gcc-ranlib-6 (1) - a wrapper around ranlib adding the --plugin option
x86_64-linux-gnu-gcc-ranlib-8 (1) - a wrapper around ranlib adding the --plugin option
$ whatis gcc
gcc (1) - GNU project C and C++ compiler

Wie man sieht findet whatis nur die Man-Page von gcc und apropos eine ganze Reihe Seiten die gcc als Inhalt haben.

Die folgende Tabelle beschreibt das unterschiedliche Verhalten von apropos und whatis:

apropos whatis
Durchsucht sowohl die Namen als auch die Kurzbeschreibungen der Handbuchseiten. Sucht nur im Namensfeld der Handbuchseiten.
Findet Kommandos, deren Namen man nicht kennt. Erklärt mit nicht mehr als einem Satz die Aufgabe von Kommandos, deren Namen man ganz genau kennt.
Hat fast dieselben Funktionen wie das Kommando man -k. Entspricht dem Kommando man -f.

apropos und whatis sind nicht case-sensitiv und daher führt apropos gcc und apropos GCC bzw. das Gleiche mit whatis zum gleichen Ergebnis.

locate

locate ein völlig anders gearteter Befehl als die zuvor. locate arbeitet mit einer Datenbank von Dateinamen die durch updatedb generiert und aktualisiert wird. updatedb läuft normalerweise auch als täglicher Cron-Job. Dabei werden alle Dateinamen im Dateisystem in der Datenbank aufgenommen und gespeichert. Diese Datenbank kann durchaus ein Sicherheitsrisiko darstellen da unabhängig von den Leserechten alle Dateinamen archiviert werden. Ein Dateiname der eben nicht für alle Benutzer sichtbar sein soll wird trotzdem aufgenommen. Auf der anderen Seite ist locate ein ziemlich schneller und praktischer Befehl.

 $ locate sshd_config
/etc/ssh/sshd_config
/usr/share/man/man5/sshd_config.5.gz
/usr/share/openssh/sshd_config
/usr/share/openssh/sshd_config.md5sum
/var/lib/ucf/cache/:etc:ssh:sshd_config

Wie man sieht wird tatsächlich jede Datei die irgendwo auf das Muster „sshd_config“ zutrifft angezeigt. locate ist case-sensitiv und durch die Option -i kann man die Suche mit locate case-unsensitiv machen. Man kann jedoch updatedb über die Konfigurationsdatei /etc/updatedb dazu bringen zum Beispiel die Verzeichnisse /root und /home und Unterverzeichnisse von der Suche auszuschließen. Dies kann einfach durch hinzufügen der Verzeichnisse in der Zeile:

PRUNEPATHS="/tmp /var/spool /media /var/lib/os-prober /var/lib/ceph /home /root"

geschehen. Die Datenbank muss danach natürlich wieder neu eingelesen werden.

2 Gedanken zu „Suchbefehle in der Linux-Konsole (I)“

Kommentare sind geschlossen.

kais-universum.de