Linux-Tail-Befehl

Der Linux-Tail-Befehl gehört zu den essenziellen Werkzeugen auf der Kommandozeile. In erster Linie dient der Befehl dazu, das Ende einer (Text)-Datei auszugeben, bzw. die Ausgabe eines Linux-Befehls auf einen gegebenen Umfang zu beschränken. Damit steht der Linux-Tail-Befehl in einer Reihe mit dem Linux-Head-Befehl und den Befehlen 'cat' und 'less'. Die genannten Linux-Befehle werden allesamt eingesetzt, um die Inhalte von Textdateien auszugeben.

Der Linux-Tail-Befehl ist Teil der GNU Core Utilities (Coreutils). Es handelt sich dabei um eine Sammlung grundlegender Befehle für die Kommandozeile, welche im Open Source Betriebssystem Linux enthalten sind. Die Coreutils sind unter einer Open Source Lizenz veröffentlicht und stehen für eine Vielzahl unterschiedlicher Betriebssysteme zum Download bereit.

Motivation des Linux-Tail-Befehls

Die Grundlegende Funktionalität des Linux-Tail-Befehls besteht darin, das Ende einer Datei auszugeben. Dazu sollten Sie wissen, dass Daten, die in eine Datei geschrieben werden, am Ende der Datei landen. Der Linux-Tail-Befehl erlaubt uns also, zu überprüfen, ob einer Datei neue Daten angehängt wurden. Daher ist der Linux-Tail-Befehl beliebt, um Logdateien auszuwerten und zu überwachen.

Viele Programme, insbesondere Webserver wie Apache oder nginx schreiben Status-Informationen in sogenannte Logdateien. Im Falle von Server-Logs enhalten die Dateien pro Zeile u. A. einen Zeitstempel, die URL der abgefragten Resource und die IP-Adresse der anfragenden Partei.

Die Logdateien wachsen mit jeder einzelnen Anfrage und werden dabei immer größer. Um die Größe ab einem bestimmten Punkt zu begrenzen, werden Logdatien für gewöhnlich „rotiert“. Die Logdatei wird dabei komprimiert und unter einem neuen Namen archiviert. Ferner wird eine neue, leere Logdatei unter dem ursrpünglichen Namen angelegt. Hier eine Übersicht gebräuchlicher Logdateien unter Ubuntu-Linux:

Unbuntu-Linux Logdatei

Erklärung

/var/log/auth.log

Linux Authorisierungs-Log

/var/log/daemon.log

Linux Daemon-Log

/var/log/debug

Linux Debug-Log

/var/log/kern.log

Linux Kernel-Log

/var/log/syslog

Linux System-Log

/var/log/apache2/access.log

Zugriffe auf Webinhalte des Apache2-Webservers

/var/log/apache2/error.log

Fehlermeldungen des Apache2-Webservers

Aufruf des Linux-Tail-Befehls auf der Kommandozeile

Der Aufruf des Linux-Tail-Befehls erfolgt auf der Kommandozeile. Wie üblich wird der Name des Befehls gefolgt von optionalen Parametern eingegeben. Abgeschlossen wird der Aufruf vom Namen bzw. Pfad einer oder mehrerer Dateien. Schauen wir uns zunächst die Schreibweise des generellen Falls an:

tail [optionen] <dateien>

Ohne Optionen ergibt sich als simpelster Aufruf des Linux-Tail-Befehls das folgende Muster:

tail <datei>

So aufgerufen, gibt der Linux-Tail-Befehl die letzten zehn Zeilen der angegebenen Datei aus. Dies ist nützlich, um die zuletzt in die Datei geschriebenen Daten anzusehen.

Grundlegende Optionen des Linux-Tail-Befehls

Der Linux-Tail-Befehl lässt sich über Parameter steuern. Als Teil der GNU Coreutils gibt es für jede Option eine Langform. Für die am häufigsten genutzten Optionen gibt es ferner eine oft historisch bedingte Kurzform. Wir zeigen hier eine Übersicht der nützlichsten Optionen:

Option (Kurzform / Langform)

Erklärung

-n / --lines

Ausgabe auf die letzten n Zeilen begrenzen / Ausgabe auf die ab Zeile n folgenden Zeilen beschränken

-c / --bytes

Ausgabe auf die letzten n Bytes begrenzen / Ausgabe auf die ab Byte n folgenden Bytes beschränken

-q / --quiet, --silent

Bei Nutzung mit mehreren Dateien Ausgabe der Dateinamen unterdrücken

-v / --verbose

Bei Nutzung mit mehreren Dateien Ausgabe der Dateinamen erzwingen

--help

Hilfsinformationen des Befehls ausgeben

--version

Versionsinformationen des Befehls ausgeben

Hinweis

Der Linux-Tail-Befehl ist primär für die Nutzung mit Textdateien im ASCII|-Zeichensatz konzipiert. Für diese gilt, dass ein Zeichen genau einem Byte entspricht. Wenn Sie Dateien im Unicode-Zeichensatz mit der '-c'-Option des Linux-Tail-Befehls verarbeiten, kann es ggf. zu unerwarteten Nebeneffekten kommen.

Weitergehende Optionen des Linux-Tail-Befehls

Die bereits gezeigten grundlegenden Optionen des Linux-Tail-Befehls sind in ihrer Funktionsweise analog zu denen des Head-Befehls. Während der Head-Befehl jedoch den Anfang einer Datei ausgibt, liefert der Linux-Tail-Befehl das Ende einer Datei. Der Befehl kann aber noch einiges mehr.

Insbesondere bietet der Linux-Tail-Befehl eine Vielzahl von Optionen, um Dateien auf Änderungen zu überwachen. Mit dem Linux-Tail-Befehl lassen sich am Ende der Datei hinzugekommen Daten kontinuierlich ausgeben. Daher ist das Kommando besonders geeignet, um Logdateien zu überwachen. Dieser Prozess ist auch als „Live-Tail“ bekannt. Hier eine Übersicht der dabei am häufigsten zum Einsatz kommenden Optionen:

Option (Kurzform / Langform)

Erklärung

-f / --follow=[{name|descriptor}]

Datei auf Änderungen überwachen und neu an das Ende der Datei geschriebene Daten kontinuierlich ausgeben. Ohne Angabe eines Wertes nach '--follow=' wird 'descriptor' als Default-Wert verwendet. Damit läuft der Live-Tail auch weiter, wenn die Datei umbenannt oder verschoben wird.

-F

Entspricht Aufruf mit --follow=name --retry; der Effekt ist, dass der Live-Tail auch dann weiterläuft, wenn die ursprüngliche Datei im Zuge der Logrotation entfernt und durch eine neue Datei mit gleichem Namen ersetzt wird.

-s / --sleep-interval=N

Ausgabe der Datei für die angegebene Anzahl Sekunden ruhen gelassen.

--retry

Versuchen, eine nicht verfügbare Datei erneut zu öffnen, sobald sie wieder verfügbar wird. Ist insbesondere in Kombination mit der Option '--follow=name' sinnvoll, um nach Rotation einer Logdatei die neue Datei gleichen Namens weiterhin zu überwachen.

--pid=PID

Mit der Option -f genutzt, wird der Tail-Befehl beendet, wenn der Prozess mit der angegebenen Prozess-ID terminiert. Nützlich, um den Live-Tail abzubrechen, wenn das in die Datei schreibende Programm beendet wird.

Beispiele für den Einsatz des Linux-Tail-Befehls

In der Dokumentation der Coreutils ist der Linux-Tail-Befehl im Abschnitt „Output of parts of files“ („Teile von Dateien ausgeben“) aufgeführt. Dabei sollten Sie wissen, dass der Begriff „Dateien“ hierbei weit gefasst ist. Präziser ist der Begriff „Textströme”.

Der Unix-Philosophie folgend nutzen Kommandozeilen-Befehle Textströme als universelles Ein- und Ausgabeformat. Bei Textströmen handelt es sich insbesondere um Dateien, jedoch auch um die Standardeingabe und -ausgabe der Kommandozeile. Ferner sind die sogenannten „Pipes”, zu Deutsch in etwa „Rohrleitungen”, von großer Wichtigkeit. Diese erlauben das Verketten mehrerer Befehle. Dabei wird die Ausgabe eines Befehls als Eingabe an den nächsten Befehl weitergereicht.

Die zugrundeliegende Idee, mehrere Befehle miteinander zu verketten, geht wiederum auf die Unix-Philosophie zurück. Anstatt komplexe Befehle für gänzlich verschiedene Aufgaben zu entwickeln, gibt es eine relativ überschaubare Menge genereller Befehle. Der Maxim „do one thing, and do it well“ („mach nur eine Sache, aber mache sie gut“) folgend, verfügt ein jeder Befehl über eine eng umrissene Funktionalität. Die Befehle nutzen Textströme als universelle Schnittstelle und lassen sich zu immer wieder neuen Lösungsansätzen kombinieren.

Hinweis

In den nachfolgenden Beispielen nutzen wir beim Aufruf des Linux-Tail-Befehls die Optionen in der Kurzform ('-n', statt '--lines', etc.) Wenn Sie andere Dokumentationen oder Code-Beispiele lesen, werden Sie häufige auf diese Verwendung stoßen.

Generelle Beispiele für den Einsatz des Linux-Tail-Befehls

Die nachfolgenden generellen Beispiele greifen auf die eingangs dargestellten grundlegenden Optionen des Linux-Tail-Befehls zurück. Für Beispiele, welche die weiterführenden Optionen nutzen, lesen Sie den Abschnitt über die Überwachung von Logdateien weiter unten.

Die meisten dargestellten Beispiele kombinieren den Linux-Tail-Befehl mit einem oder mehreren weiteren Linux-Befehlen. Dabei kommen die erwähnten Pipes zum Einsatz, um die Ausgabe eines Befehls als Eingabe des nächsten Befehls zu nutzen.

Mit dem Linux-Tail-Befehl das Ende einer Datei ausgeben

Im einfachsten Falle nutzen wir den Linux-Tail-Befehl, um die letzten Zeilen einer Datei auszugeben. Um dies auszuprobieren, ersetzen Sie den Platzhalter '<datei>' durch den Namen bzw. Pfad einer auf Ihrem System existierenden Textdatei. Hier nutzen wir die -n-Option und geben die letzten drei Zeilen einer Datei aus:

tail -n 3 <datei>

Oft ist es nützlich, den Kontext der mit dem Linux-Tail-Befehl verarbeiteten Datei im Auge zu behalten. Um die Zeilen mit Zeilennummern versehen auszugeben, verarbeiten wir die Datei zunächst mit dem nl-Befehl (der Name stammt von „line numbering“— „Zeilennummerierung“) und leiten die Ausgabe per Pipe an den Linux-Tail-Befehl weiter:

nl <datei> | tail -n 3

Zuletzt benutzte Befehle auf der Kommandozeile ausgeben

Der History-Befehl zeigt auf der Kommandozeile eingegebene Befehle an. Oft interessiert man sich nur für die letzten Aufrufe. Ferner kann eine komplette Ausgabe der Befehls-History u. U. sensible Daten enthüllen. Hier leiten wir die Ausgabe des History-Befehls an den Linux-Tail-Befehl weiter und geben die letzten fünf Zeilen aus:

history | tail -n 5

Mit dem Linux-Tail-Befehl die ältesten Backup-Dateien in einem Verzeichnis löschen

Schauen wir uns ein komplexeres Beispiel an. Wir werden aus einem Verzeichnis mit Backup-Dateien die zehn ältesten Dateien löschen. Um dies zu bewerkstelligen, nutzen wir die vier Linux-Befehle 'ls', 'tail', 'xargs' und 'rm':

ls -t *.bak | tail | xargs rm

Was genau geschieht hier?

  1. Der ls-Befehl listet die Dateien eines Verzeichnisses auf.

Mit der '-t'-Option versehen, werden die Dateien nach Änderungsdatum sortiert. Dabei stehen die ältesten Dateien ganz unten in der Liste.

Wir nutzen für die Datenquelle das Suchmuster '*.bak'. Dabei handelt es sich um eine gebräuchliche Datei-Endung für Backup-Dateien. Ferner dient dies zum Schutz, damit Sie beim Aufruf nicht aus Versehen wichtige Dateien löschen.

Per Pipe leiten wir die Dateiliste an den Linux-Tail-Befehl weiter.

  1. Mit dem Linux-Tail-Befehl ohne Angabe von Optionen lesen wir die letzten zehn Dateien aus der Liste aus. Bei den ausgegebenen Dateinamen handelt es sich um die ältesten Dateien im Verzeichnis.
  2. Der xargs-Befehl nimmt eine Liste von Dateien und den Namen eines Befehls entgegen. Der Befehl wird ausgeführt, wobei die Dateien als Argumente übergeben werden.

In unserem Beispiel gibt der Linux-Tail-Befehl einen Text mit mehreren Zeilen zurück. Jede Zeile enthält den Namen einer zu löschen Datei. Per 'xargs' werden die Dateinamen aus den Zeilen gelöst und als Argumente dem rm-Befehl übergeben.

  1. Zum Löschen von Dateien unter Linux greifen wir auf den rm-Befehl zurück. Dieser löscht die als Argumente übergebenen Dateien.

Beachten Sie, dass die Dateien nicht in den Papierkorb verschoben, sondern sofort gelöscht werden.

Beim Löschen von Dateien auf der Linux-Kommandozeile ist Vorsicht geboten. Damit Sie unser Beispiel ohne Sorge ausprobieren können, sollten Sie zunächst ein Verzeichnis mit Test-Dateien anlegen. Führen Sie dafür den folgenden Code auf der Kommandozeile aus:

mkdir ~/Desktop/tail-test/
cd ~/Desktop/tail-test/
touch test-{1..100}.bak

Zunächst legen wir ein Test-Verzeichnis 'tail-test/' auf dem Desktop an und wechseln in das Verzeichnis. Anschließend erzeugen wir 100 leere Test-Dateien mit den 'test-1.bak' bis 'test-100.bak'. Führen Sie danach den Code zum Löschen der zehn ältesten Dateien aus:

ls -t ~/Desktop/tail-test/*.bak | tail | xargs rm

Mit dem Linux-Tail-Befehl Server-Logdateien auf Änderungen überwachen

Bisher haben wir die generelle Funktionsweise des Linux-Tail-Befehls betrachtet. In den folgenden Beispielen legen wir den Fokus auf die Live-Überwachung von Server-Logdateien („Live-Tail“).

In diesen Beispielen gehen wir vom Apache2-Webserver unter Ubuntu-Linux aus. Dort liegen die Logdateien im Verzeichnis '/var/log/apache2/'. Auf anderen Linux-Distributionen ist der Speicherort ggf. ein anderer. Gleiches gilt bei anderen Webservern, wie etwa nginx.

Hinweis

Eventuell hat nur der Root-Benutzer Zugriff auf das Verzeichnis mit Logdateien. In diesem Fall müssten Sie die Befehle mit 'sudo' ausführen.

Mit dem Linux-Tail-Befehl eine Server-Logdatei auf Änderungen überwachen

Ein normaler Aufruf des Linux-Tail-Befehls gibt einmalig die angegebene Anzahl Zeilen einer Datei aus. Werden danach neue Daten am Ender Datei angehängt, muss der Befehl erneut ausgeführt werden. Genau für diesen Fall gibt es weiterführende Optionen. Diese weisen das Kommando an, eine Datei auf Änderungen zu überwachen und diese kontinuierlich auszugeben.

Schauen wir uns an, wie das am Beispiel des Zugriffs-Logs des Apache2-Webserver funktioniert. Wir rufen den Linux-Tail-Befehl mit der -f-Option auf und übergeben den Namen der Logdatei:

tail -f /var/log/apache2/access.log

So aufgerufen, werden Änderungen am Zugriffs-Log kontinuierlich ausgegeben. Dieser Ansatz ist bei vielen Zugriffen pro Zeiteinheit nicht praktikabel. In diesem Falle ändert sich das Log so schnell, dass das Terminal mit Daten überflutet wird. Drücken Sie die Tastenkombination 'Strg+C', um die laufende Ausführung des Live-Tails abzubrechen.

Mit der Option '-f' aufgerufen, überwacht der Linux-Tail-Befehl die angegebene Datei. Wird diese entfernt, bricht die Ausgabe ab. Wie eingangs erklärt, werden Logdateien periodisch rotiert. Es wird also eine neue Datei unter dem alten Namen angelegt. Um die Überwachung einer Log-Datei trotz Rotation fortzusetzen, nutzen wir die -F-Option:

tail -F /var/log/apache2/access.log

Mit dem Linux-Tail-Befehl mehrere Server-Logdateien auf Änderungen überwachen

Bisher haben wir mit dem Linux-Tail-Befehl eine einzelne Datei verarbeitet. Der Befehl erlaubt jedoch auch die Überwachung mehrerer Dateien gleichzeitig. Hier nutzen wir das Suchmuster '*.log', um alle Dateien mit der Endung '.log' kontinuierlich zu überwachen:

tail -F /var/log/apache2/*.log

Für die Verarbeitung mehrerer Dateien gibt es zwei weitere Optionen. Zum einen können wir mit der '-q'-Option die Ausgabe der Dateinamen unterdrücken:

tail -q -F /var/log/apache2/*.log

Analog dazu lässt sich mit der -v-Option die Ausgabe der Dateinamen erzwingen. Dies macht Sinn, falls das Suchmuster nur eine einzelne Datei zurückliefert:

tail -v -F /var/log/apache2/*.log

Mit dem Linux-Tail-Befehl eine Server-Logdatei auf spezifische Änderungen überwachen

In den bisherigen Beispielen haben wir eine Logdatei auf jedwede Änderung hin überwacht. Gebräuchlicher ist jedoch die Einschränkung auf bestimmte Änderungen. Um die Ausgabe der Änderungen einer Logdatei auf ein Suchmuster zu begrenzen, nutzen wir den grep-Befehl. Hier ein generelles Beispiel für diesen Ansatz:

tail -F /var/log/apache2/access.log | grep <muster>

Konkret ist es oft sinnvoll, einen Server-Log auf den Zugriff durch eine bestimmte IP-Adresse zu überwachen. Dies kann beispielsweise nützlich sein, um festzustellen, ob ein Angriff auf einen Server bereits abgeschlossen ist oder noch läuft. Hier überwachen wir das Zugriffs-Log des Apache-Webserver auf von der IP-Adresse '93.184.216.34' stammende Anfragen:

tail -F /var/log/apache2/access.log | grep '93.184.216.34'
Hinweis

Wir benutzen hier die IP-Adresse der Beispiel-Domain 'example.com'. Sollte ein Zugriffs-Log diese tatsächlich enthalten, handelt es sich mit hoher Wahrscheinlichkeit um eine gespoofte IP-Adresse.

Schauen wir uns ein weiteres geläufiges Einsatz-Szenario an. Anstatt das Zugriffs-Log nach IP-Adresse zu filtern, überwachen wir Zugriffe auf eine bestimmte Ressource. Ein Zugriff auf die Datei 'robots.txt' weist auf Anfragen von Suchmaschinen-Bots hin. Wiederum machen wir uns den Grep-Befehl zunutze. So aufgerufen werden nur neu hinzukommende Zugriffe von Suchmaschinen-Bots ausgegeben:

tail -F /var/log/apache2/access.log | grep 'robots.txt'