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:
timeout
verwendet immerSIGKILL
als letztes Signal.timeout
hat 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