Eigentlich ist das timeout ist für:
TIMEOUT(1) User Commands TIMEOUT(1)
NAME
timeout - run a command with a time limit
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
DESCRIPTION
Start COMMAND, and kill it if still running after DURATION.
[email protected]:~$ dpkg -S /usr/bin/timeout
coreutils: /usr/bin/timeout
Es gibt (mindestens) zwei Programme, die diese Funktionalität bieten:
NAME
timelimit — die absolute Ausführungszeit eines Prozesses effektiv begrenzen
SYNOPSIS
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
und
NAME
timeout - Führen Sie einen Befehl mit einem Zeitlimit aus
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
Sie sind wie folgt verpackt:
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
Vergleich:
/-----------------------------+------------+----------------\
| Feature | timelimit | timeout |
+=============================+============+================+
| time to run | -t time | first argument |
+-----------------------------+------------+----------------+
| terminate signal | -s signal | -s signal |
+-----------------------------+------------+----------------+
| grace period | -T time | -k time |
+-----------------------------+------------+----------------+
| kill signal | -S signal | (note 1) |
+-----------------------------+------------+----------------+
| propagate signals | -p | (note 2) |
\-----------------------------+------------+----------------/
Hinweise:
timeoutverwendet immerSIGKILLals letztes Signal.timeouthat keine Funktion, um mit einem Signal zu beenden, wenn das untergeordnete Programm dies tut.
Der Exit-Status der beiden Programme unterscheidet sich, aber das ist schwer sauber zusammenzufassen, also schlage ich vor, dass Sie die Manpages selbst dazu konsultieren.
Als timeout ist standardmäßig auf mehreren Systemen installiert (coreutils ein Standardpaket in vielen Distributionen ist), schlage ich vor, dass Sie es verwenden, es sei denn, Sie benötigen die zusätzliche Funktionalität, die von timelimit bereitgestellt wird .
Reines bash eingebaut, ohne coreutils
Ich habe festgestellt, dass diese Lösung in bash funktioniert sich auf ein integriertes verlassen Befehl, ohne eine externe ausführbare Datei aufzurufen. Es funktioniert auf Systemen, auf denen eventuell nicht einmal die Coreutils installiert sind
YourCommand & read -t 300 ; kill $! # 1st version
YourCommand & read -t 300 || kill $! # 2nd version
Erklärungen :wie gewohnt, wenn Sie im Hintergrund einen Befehl mit & senden , seine PID wird in der internen Variable $! gespeichert (vorhanden in der modernen Version von dash , csh , bash , tcsh , zsh ...).
Was wirklich den Unterschied zwischen den Shells ausmacht, ist das Vorhandensein der eingebauten Befehl read und der Option -t .In der 1. Version, wenn der Benutzer eine Eingabezeile nicht vor Ablauf der angegebenen Sekunden vervollständigt, wird die Anweisung beendet und ein Fehlerrückgabecode generiert.
Die zweite Version funktioniert wie die erste, aber Sie können das Killing-Timeout abbrechen, indem Sie einfach enter drücken .
Tatsächlich der or-Operator || führt den kill aus Anweisung nur, wenn read Der Befehl wird mit einem von Null verschiedenen Rückkehrcode beendet, wie wenn das Zeitlimit abgelaufen ist. Wenn Sie Enter drücken Vor diesem Moment wird 0 zurückgegeben und Ihr vorheriger Befehl wird nicht beendet.
Coreutils-Lösungen
Wenn coreutils auf Ihrem System vorhanden sind und Sie keine Zeit und Ressourcen sparen müssen, um ein externes Programm aufzurufen, timeout und sleep und sind beide perfekte Wege, um Ihr Ziel zu erreichen.
timeout Die Verwendung von timeout ist geradeaus.
Eventuell können Sie auch den -k verwenden Option, ein zusätzliches Kill-Signal zu senden, wenn das erste fehlschlägt.
timeout 5m YourCommand # 3rd version
sleep Mit sleep Sie können Ihrer Fantasie freien Lauf lassen oder sich inspirieren lassen. Beachten Sie, dass Sie Ihren Befehl im Hintergrund oder im Vordergrund belassen können (z. B. top muss normalerweise im Vordergrund sein).
YourCommand & sleep 5m; kill $! # 4th Background
YourCommand & pid=$! ; (sleep 5m; kill $pid;) & # 5th Background
bash -c '(sleep 5m; kill $$) & exec YourCommand' # 6th Foreground
(cmdpid=$BASHPID; (sleep 5m; kill $cmdpid) & exec YourCommand) # 7th Foreground
Erklärungen
Natürlich können Sie in jeder Version das Kill-Signal senden, das Sie brauchen, vom Standard- bis zum extremen kill -9 , nur zu verwenden, wenn es wirklich nötig ist.
Referenzen
- [1] Die Coreutils
- [2] Der Bash-Anfängerleitfaden
- [3] Die BashFAQ