Es gibt (mindestens) zwei Programme, die diese Funktionalität bereitstellen:
NAME
timelimit
- Begrenzen Sie effektiv die absolute Ausführungszeit eines Prozesses
ZUSAMMENFASSUNG
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
und
NAME
timeout
- einen zeitlich begrenzten Befehl ausführen
ZUSAMMENFASSUNG
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) |
\-----------------------------+------------+----------------/
Anmerkungen:
timeout
wird immer SIGKILL
als letztes Signal verwendet.
timeout
hat keine Funktionalität, um mit einem Signal zu beenden, wenn das untergeordnete Programm dies tut.
Der Exit-Status der beiden Programme ist unterschiedlich, lässt sich aber nur schwer übersichtlich zusammenfassen. Ich empfehle daher, dass Sie die Handbuchseiten selbst zu Rate ziehen.
Da timeout
es standardmäßig auf mehreren Systemen installiert ist (dies coreutils
ist ein Standardpaket in vielen Distributionen), empfehle ich Ihnen, dies zu verwenden, es sei denn, Sie benötigen die zusätzlichen Funktionen von timelimit
.
timelimit
. Siehe Wie kann ich einen Prozess beenden und sicherstellen, dass die PID nicht wiederverwendet wurde, um weitere Informationen zu diesen und zum GNU-Timeout zu erhalten?timeout
ist in GNU coreutils enthalten ,timelimit
ist es nicht. Sie können keine, eine oder beide installiert haben. Für die Sekunde wird gemeldet, dass timelimit einen Befehl ausführt und den erzeugten Prozess nach einer bestimmten Zeit mit einem bestimmten Signal beendet. Zuerst wird ein Warnsignal gesendet , dann nach einer Zeitüberschreitung ein Kill-Signal, ähnlich wie init (8) beim Herunterfahren arbeitet. Also noch ein anderes im mittleren Verhalten.timeout
ist der Weg dorthin.Eigentlich ist das, was
timeout
ist für:quelle
Rein
bash
eingebaut, ohne CoreutilsIch fand heraus, dass diese Lösung
bash
auf einem eingebauten Befehl beruht, ohne eine externe ausführbare Datei aufzurufen. Es funktioniert auf Systemen, auf denen eventuell noch nicht einmal die Coreutils installiert wurden. [ 1 ]Erläuterungen : wie immer , wenn Sie einen Befehl im Hintergrund senden mit
&
, seine PID in die interne Variable gespeichert$!
(in der modernen Version vondash
,csh
,bash
,tcsh
,zsh
...).Was wirklich den Unterschied zwischen den Shells ausmacht, ist das Vorhandensein des eingebauten Befehls
read
[ 2 ] und der Option-t
. In der 1. Version wird der Befehl abgebrochen und ein Fehlerrückgabecode generiert, wenn der Benutzer eine Eingabezeile nicht vor der angegebenen Anzahl von Sekunden abschließt.Die zweite Version funktioniert wie die erste, aber Sie können die Abschaltzeit abbrechen, indem Sie einfach auf drücken enter.
In der Tat
||
führt der Operator oder diekill
Anweisung nur dann aus, wenn derread
Befehl mit einem von Null verschiedenen Rückkehrcode beendet wird, als wenn das Zeitlimit abgelaufen ist. Wenn Sie entervor diesem Moment drücken , wird 0 zurückgegeben und der vorherige Befehl wird nicht beendet.Coreutils-Lösungen [ 1 ]
Wenn auf Ihrem System Coreutils vorhanden sind und Sie nicht die Zeit und die Ressourcen zum Aufrufen eines externen Programms sparen müssen,
timeout
undsleep
beides perfekte Möglichkeiten, um Ihr Ziel zu erreichen.timeout
Die Verwendungtimeout
ist unkompliziert.Möglicherweise können Sie auch die
-k
Option verwenden, ein zusätzliches Kill-Signal zu senden, wenn das erste fehlschlägt.sleep
Mit könnensleep
Sie Ihre Fantasie nutzen oder sich inspirieren lassen [ 3 ] . Beachten Sie, dass Sie Ihren Befehl im Hintergrund oder im Vordergrund lassen können (z. B. musstop
normalerweise im Vordergrund sein).Erklärungen
YourCommand
dann Ihre Shellsleep
s für 5 Minuten aus. Wenn es fertig ist, wird der letzte Hintergrundprozess ($!
) abgebrochen. Sie stoppen Ihre Muschel.YourCommand
und speichern diese PID sofort in der Variablen$pid
. Anschließend führen Sie im Hintergrund ein Nickerchen von 5 Minuten und den darauf folgenden Befehl aus, mit dem die gespeicherte PID gelöscht wird. Da Sie diese Befehlsgruppe im Hintergrund gesendet haben, stoppen Sie Ihre Shell nicht. Sie müssen die PID in einer Variablen speichern, da der Wert von$!
durch eine eventuelle Ausführung eines anderen Programms im Hintergrund aktualisiert werden kann. Mit einfachen Worten vermeiden Sie das Risiko , den falschen oder gar keinen Prozess zu beenden.$$
. Dann wird Ihr Befehl ausgeführt, der im Vordergrund bleibt.()
, die ihre PID in einer Variablen (cmdpid
) speichert und sich mit einer anderen Subshell beendet, die im Hintergrund gesendet wird. Führen Sie dann YourCommand im Vordergrund aus.Natürlich können Sie in jeder Version das Kill-Signal senden, das Sie benötigen, vom Standard-Signal bis zum Extrem- Signal
kill -9
, um es nur dann zu verwenden, wenn es wirklich benötigt wird.Verweise
quelle
Für Ihren speziellen Fall, die meisten Implementierungen der
ping
Unterstützung-c
oder--count
nach einer bestimmten Anzahl von Pings zu beenden:Eine allgemeinere Lösung finden Sie in den anderen Antworten.
quelle
ping
für ein konkretes Beispiel vorgesehen ist. Er möchte nicht für jedes Programm eine Einzellösung.Sie können dies mit einem einfachen Skript wie dem folgenden tun:
(Signal SIGINT = 2 gemäß dem Vorschlag von Matija Nalis im Kommentar unten).
Eine Erklärung des (ungewöhnlichen?) Bash-Ausdrucks
$@:...
: Die Positionsparameter ($*, $@, "$*", "$@"
) lassen zum Beispiel die folgende zusätzliche Spezifikation zu:was bedeutet: von allen Parametern wird COUNT genommen, wobei der erste an der START-Position genommen wird; Wenn COUNT weggelassen wird, nehmen Sie alle bis zum Ende, beginnend mit der START-Position. Denken Sie daran, dass dies
$0
der Programmname ist. Wenn START negativ ist, beginnen Sie mit der Zählung am Ende und denken Sie daran, dass COUNT nicht negativ sein kann, daher lautet das letzte Argument"${@:-1}"
. Fügen Sie außerdem die Positionsparameter fast immer in doppelte Anführungszeichen ein.quelle
$1
ist ziemlich grob. Sie könnten auch einfachsleep "$1"
oder etwas incountdown
.time=$1; shift
und benötigen dann nicht die Array-Slicing-Syntax für die Positionsparameter. Aber ja, das ist viel einfacher.ctrl-c
, ist es wahrscheinlich besser, eskill -INT
stattdessen zu versuchenkill -9
(oder es zumindest-9
erst nach wenigen Sekunden zu versuchen, wenn das erste nicht erfolgreich war - es gibt dem Programm die Möglichkeit, sauber zu beenden und keine temporären Dateien zu hinterlassen usw.)Da erwähnen Sie
ping
in Ihrem Beispiel; Dieser Befehl hat einige Optionen, um nach einer bestimmten Zeit anzuhalten:quelle