So verwenden Sie den Timeout-Befehl unter Linux

Genug Zeit am Computer! Mit dem Befehl timeout können Sie die Ausführungszeit von Prozessen begrenzen. Sie legen einfach ein maximales Zeitlimit fest, innerhalb dessen ein Prozess abgeschlossen sein muss. Diese Anleitung zeigt Ihnen, wie Sie Programme mit diesem Befehl einschränken.

Was bewirkt Timeout?

Der Befehl timeout ermöglicht es Ihnen, die Laufzeit eines Programms zu limitieren. Aber warum sollte man das tun wollen?

Ein typischer Fall ist, wenn Sie die erwartete Laufzeit eines Prozesses genau kennen. Oft wird timeout genutzt, um Protokollierungs- oder Datenerfassungsprogramme zu steuern, damit die Protokolldateien nicht unkontrolliert Ihren Speicherplatz füllen.

Ein anderer Fall tritt ein, wenn Sie die Laufzeit eines Prozesses nicht genau kennen, aber sicherstellen wollen, dass er nicht endlos läuft. Vielleicht tendieren Sie dazu, Prozesse zu starten, das Terminalfenster zu minimieren und sie dann zu vergessen.

Manche Programme, selbst einfache Dienstprogramme, können Netzwerkverkehr erzeugen, der die Netzwerkleistung beeinträchtigen kann. Oder sie belegen Ressourcen auf einem Zielgerät und verlangsamen dessen Funktion. (Ich schaue dich an, Ping!). Es ist keine gute Idee, solche Programme über längere Zeit laufen zu lassen, während Sie nicht an Ihrem Computer sind.

timeout ist Bestandteil der GNU Core Utilities. Linux und Unix-ähnliche Systeme wie macOS haben timeout direkt eingebaut. Es ist keine Installation notwendig; Sie können es sofort verwenden.

Erste Schritte mit Timeout

Hier ist ein einfaches Beispiel: Standardmäßig läuft der ping-Befehl, bis Sie ihn mit Strg+C abbrechen. Ohne Unterbrechung läuft er endlos weiter.

ping 192.168.4.28

Mit timeout können wir sicherstellen, dass ping nicht ständig läuft, die Netzwerkbandbreite beansprucht und jedes Gerät, das angepingt wird, unnötig belastet.

Der folgende Befehl nutzt timeout, um die Laufzeit von ping zu begrenzen. Wir erlauben ping eine Laufzeit von 15 Sekunden.

timeout 15 ping 192.168.4.28

Nach 15 Sekunden beendet timeout die ping-Sitzung und wir kehren zur Befehlszeile zurück.

Timeout mit anderen Zeiteinheiten

Beachten Sie, dass wir hinter der ’15‘ kein „s“ für Sekunden hinzufügen mussten. Sie könnten ein „s“ hinzufügen, aber es macht keinen Unterschied.

Um einen Zeitwert in Minuten, Stunden oder Tagen anzugeben, fügen Sie ein „m“, „h“ oder „d“ hinzu.

Um ping drei Minuten lang laufen zu lassen, verwenden Sie diesen Befehl:

timeout 3m ping 192.168.4.28

ping wird drei Minuten lang ausgeführt, bevor timeout es beendet.

Datenerfassung mit Timeout einschränken

Einige Datenerfassungsdateien können sehr schnell anwachsen. Um zu verhindern, dass solche Dateien unübersichtlich oder sogar problematisch werden, begrenzen Sie die Zeit, die ein Erfassungsprogramm laufen darf.

In diesem Beispiel verwenden wir tcpdump, ein Werkzeug zur Erfassung von Netzwerkverkehr. Auf den Testsystemen, auf denen dieser Artikel recherchiert wurde, war tcpdump bereits unter Ubuntu Linux und Fedora Linux installiert. Unter Manjaro Linux und Arch Linux musste es mit diesem Befehl installiert werden:

sudo pacman -Syu tcpdump

Wir können tcpdump mit seinen Standardoptionen für 10 Sekunden ausführen und die Ausgabe in eine Datei namens capture.txt umleiten:

timeout 10 sudo tcpdump > capture.txt

(tcpdump hat eigene Optionen, um den erfassten Netzwerkverkehr in einer Datei zu speichern. Dies ist ein schneller Hack, da wir uns hier mit timeout und nicht mit tcpdump beschäftigen.)

tcpdump beginnt mit der Erfassung des Netzwerkverkehrs und wir warten 10 Sekunden. Aber auch nach 10 Sekunden läuft tcpdump noch und capture.txt wächst weiter. Um tcpdump zu stoppen, benötigen Sie ein schnelles Strg+C.

Eine Überprüfung der Größe von capture.txt mit ls zeigt, dass sie innerhalb von Sekunden auf 209K angewachsen ist. Diese Datei wuchs schnell!

ls -lh capture.txt

Was ist passiert? Warum hat timeout tcpdump nicht gestoppt?

Das hat alles mit Signalen zu tun.

Das richtige Signal senden

Wenn timeout ein Programm stoppen möchte, sendet es das SIGTERM-Signal. Dies fordert das Programm höflich auf, sich zu beenden. Manche Programme ignorieren das SIGTERM-Signal. In diesem Fall müssen wir timeout etwas deutlicher werden lassen.

Wir können das tun, indem wir von timeout verlangen, stattdessen das SIGKILL-Signal zu senden.

Das SIGKILL-Signal kann nicht „abgefangen, blockiert oder ignoriert“ werden – es kommt immer durch. SIGKILL fordert das Programm nicht höflich auf, zu stoppen. SIGKILL lauert mit Stoppuhr und Knüppel um die Ecke.

Wir können die Option -s (Signal) verwenden, um timeout anzuweisen, das SIGKILL-Signal zu senden.

timeout -s SIGKILL 10 sudo tcpdump > capture.txt

Diesmal wird tcpdump nach 10 Sekunden beendet.

Erst höflich bitten

Wir können timeout anweisen, zuerst zu versuchen, das Programm mit SIGTERM zu stoppen und SIGKILL nur dann zu senden, wenn SIGTERM nicht funktioniert hat.

Dazu verwenden wir die Option -k (kill after). Die Option -k benötigt einen Zeitwert als Parameter.

In diesem Befehl fordern wir timeout auf, dmesg 30 Sekunden lang laufen zu lassen und es dann mit dem SIGTERM-Signal zu beenden. Wenn dmesg nach 40 Sekunden immer noch läuft, bedeutet das, dass das diplomatische SIGTERM ignoriert wurde und timeout SIGKILL senden soll, um die Aufgabe zu beenden.

dmesg ist ein Dienstprogramm, das Kernel-Ringpuffer-Meldungen überwacht und sie in einem Terminalfenster anzeigt.

timeout -k 40 30 dmesg -w

dmesg läuft 30 Sekunden lang und stoppt dann, wenn es das SIGTERM-Signal empfängt.

Wir wissen, dass es nicht SIGKILL war, das dmesg gestoppt hat, da SIGKILL immer einen Nachruf mit dem Wort „Killed“ im Terminalfenster hinterlässt. Das ist hier nicht der Fall.

Den Exit-Code des Programms abrufen

Gut erzogene Programme geben beim Beenden einen Wert an die Shell zurück. Dies wird als Exit-Code bezeichnet. Normalerweise wird er verwendet, um der Shell – oder dem anderen Prozess, der das Programm gestartet hat – mitzuteilen, ob das Programm während der Ausführung auf Probleme gestoßen ist.

timeout stellt einen eigenen Exit-Code bereit, der uns aber möglicherweise egal ist. Wir sind wahrscheinlich mehr am Exit-Code des Prozesses interessiert, den timeout steuert.

Dieser Befehl lässt ping fünf Sekunden laufen. Er pingt einen Rechner namens Nostromo an, der sich im Testnetzwerk befindet, in dem dieser Artikel recherchiert wurde.

timeout 5 ping Nostromo.local

Der Befehl wird fünf Sekunden lang ausgeführt und von timeout beendet. Wir können dann den Exit-Code mit diesem Befehl prüfen:

echo $?

Der Exit-Code ist 124. Das ist der Wert, den timeout verwendet, um anzugeben, dass das Programm mit SIGTERM beendet wurde. Wenn SIGKILL das Programm beendet, lautet der Exit-Code 137.

Wenn wir das Programm mit Strg+C unterbrechen, ist der Exit-Code von timeout Null.

timeout 5 ping Nostromo.local
echo $?

Wenn das Programm seine Ausführung beendet, bevor timeout es beendet, kann timeout den Exit-Code des Programms an die Shell zurückgeben.

Dazu muss das Programm von selbst anhalten (also nicht von timeout beendet werden) und wir müssen die Option --preserve-status verwenden.

Wenn wir die Option -c (count) mit dem Wert fünf verwenden, sendet ping nur fünf Anfragen. Wenn wir timeout eine Dauer von einer Minute geben, hat ping sich definitiv selbst beendet. Wir können dann den Exit-Wert mit echo prüfen.

timeout --preserve-status 1m ping -c 5 Nostromo.local
echo $?

ping schließt seine fünf Ping-Anfragen ab und beendet sich. Der Exit-Code ist Null.

Um zu überprüfen, ob der Exit-Code von ping stammt, zwingen wir ping, einen anderen Exit-Code zu generieren. Wenn wir versuchen, Ping-Anfragen an eine nicht existierende IP-Adresse zu senden, schlägt ping mit einem Fehler-Exit-Code fehl. Wir können dann mit echo prüfen, ob der Exit-Code ungleich Null ist.

timeout --preserve-status 1m ping -c 5 NotHere.local
echo $?

Der ping-Befehl kann das nicht existierende Gerät natürlich nicht erreichen, meldet also einen Fehler und beendet sich. Der Exit-Code ist zwei. Das ist der Exit-Code, den ping für allgemeine Fehler verwendet.

Regeln festlegen

Bei timeout geht es darum, laufenden Programmen Grenzen zu setzen. Wenn Ihre Protokolldateien die Festplatte volllaufen oder Sie vergessen, dass Sie ein Netzwerktool gestartet haben, packen Sie es in timeout und lassen Sie Ihren Computer sich selbst regulieren.