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.