Il y a (au moins) deux programmes qui fournissent cette fonctionnalité:
NOM
timelimit
- limiter efficacement le temps absolu d'exécution d'un processus
SYNOPSIS
timelimit [-pq] [-S killsig] [-s warnsig] [-T killtime] [-t warntime] command [arguments ...]
et
NOM
timeout
- lancer une commande avec une limite de temps
SYNOPSIS
timeout [OPTION] DURATION COMMAND [ARG]...
timeout [OPTION]
Ils sont emballés comme suit:
$ dlocate `which timeout timelimit`
timelimit: /usr/bin/timelimit
coreutils: /usr/bin/timeout
Comparaison:
/-----------------------------+------------+----------------\
| 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) |
\-----------------------------+------------+----------------/
Remarques:
timeout
utilise toujours SIGKILL
comme signal de dernier recours.
timeout
n'a aucune fonctionnalité pour sortir avec un signal lorsque le programme enfant le fait.
Les états de sortie des deux programmes diffèrent, mais il est difficile de les résumer soigneusement. Je vous suggère donc de consulter les pages du manuel vous-même.
Comme il timeout
est installé sur plusieurs systèmes par défaut ( coreutils
est un paquet standard dans de nombreuses distributions), je vous suggère de l’utiliser sauf si vous avez besoin des fonctionnalités supplémentaires fournies par timelimit
.
timelimit
. Voir Comment puis-je tuer un processus et m'assurer que le PID n'a pas été réutilisé pour plus d'informations sur eux et le délai d'expiration GNU.timeout
est inclus dans GNU coreutils ,timelimit
n’est pas. Vous pouvez avoir installé aucun, un ou les deux. Pour la seconde, il est signalé que timelimit exécute une commande et termine le processus généré après un temps donné avec un signal donné. Un signal "warning" est envoyé en premier , puis, après un délai d'attente, un signal "kill", similaire à la façon dont init (8) fonctionne à l'arrêt. Donc, même un comportement différent dans le milieu .timeout
c’est la voie à suivre.En fait, c’est pour ça que
timeout
:la source
Pure
bash
construit, sans coreutilsJ'ai trouvé que cette solution fonctionne en
bash
s'appuyant sur une commande intégrée sans appeler un exécutable externe. Cela fonctionne sur le système où finalement ne sont même pas installés les coreutils [ 1 ]Explications : comme d' habitude lorsque vous envoyez une commande en arrière - plan
&
, son PID est stocké dans la variable interne$!
(présent dans la version modernedash
,csh
,bash
,tcsh
,zsh
...).Ce qui fait vraiment la différence entre les obus est la présence de la commande intégrée
read
[ 2 ] et de l’option-t
. Dans la 1ère version, si l'utilisateur ne complète pas une ligne d'entrée avant le nombre de secondes spécifié, l'instruction est terminée et un code de retour d'erreur est généré.La deuxième version fonctionne comme la 1ère mais vous pouvez abandonner le délai de mise à mort en appuyant simplement sur enter.
En effet, l'opérateur ou
||
n'exécute l'kill
instruction que si laread
commande se termine avec un code retour différent de zéro, par exemple lorsque le délai d'attente a expiré. Si vous appuyez enteravant ce moment, il renverra 0 et il ne tuera pas votre commande précédente.Solutions Coreutils [ 1 ]
Lorsque coreutils sont présents sur votre système et vous avez pas besoin d'économiser le temps et les ressources nécessaires pour appeler un programme externe,
timeout
etsleep
et sont les deux moyens parfaits pour atteindre votre objectif.timeout
L'utilisation detimeout
est simple.En fin de compte, vous pouvez également utiliser l'
-k
option permettant d'envoyer un signal de neutralisation supplémentaire si le premier échoue.sleep
Avecsleep
vous pouvez utiliser votre fantaisie ou prendre des inspirations [ 3 ] . Notez que vous pouvez laisser votre commande en arrière-plan ou au premier plan (par exemple, iltop
doit généralement être au premier plan).Des explications
YourCommand
votre shellsleep
pendant 5 minutes. Quand il sera fini, le dernier processus d'arrière-plan ($!
) sera tué. Vous arrêtez votre coquille.YourCommand
- plan et vous stockez immédiatement ce PID dans la variable$pid
. Ensuite, vous exécutez en arrière-plan une sieste de 5 minutes et la commande qui en découle qui va tuer ce PID stocké. Comme vous avez envoyé ce groupe de commandes en arrière-plan, vous n'arrêtez pas votre shell. Vous devez stocker le PID dans une variable, car la valeur de$!
peut être mise à jour par l'exécution éventuelle d'un autre programme en arrière-plan. En termes simples, vous évitez le risque de tuer le mauvais processus ou aucun processus du tout.$$
, puis il exécutera votre commande qui reste au premier plan.()
- shell qui stocke son PID dans une variable (cmdpid
) et se détruit avec un autre sous-shell envoyé en exécution en arrière-plan, puis lance votre commande au premier plan.Bien sûr, dans chaque version, vous pouvez envoyer le signal de suppression dont vous avez besoin, de la valeur par défaut à l’ extrême
kill -9
, pour n’être utilisé que lorsque vous en avez vraiment besoin.Références
la source
Pour votre cas particulier, la plupart des implémentations de
ping
support-c
ou--count
à terminer après un nombre particulier de pings:Pour une solution plus générale, voir les autres réponses.
la source
ping
un exemple concret. Il ne veut pas de solution au cas par cas pour chaque programme.Vous pouvez le faire avec un script simple comme ceci:
(signal SIGINT = 2 utilisé conformément à la suggestion de Matija Nalis dans le commentaire ci-dessous).
Une explication de l'expression bash (peu commune?)
$@:...
: Les paramètres de position, ($*, $@, "$*", "$@"
) admettent la spécification supplémentaire suivante, par exemple:ce qui signifie: parmi tous les paramètres, prenez-les en COMPTE, le premier à prendre est celui à la position START; si COUNT est omis, prenez-les tous jusqu'à la fin, en commençant par la position START. Rappelez-vous que
$0
c'est le nom du programme. Si START est négatif, commencez à compter à partir de la fin et souvenez-vous que COUNT ne peut pas être négatif, d'où le dernier argument"${@:-1}"
. En outre, vous devez toujours inclure les paramètres de position entre guillemets doubles.la source
$1
est assez grossier. En outre, vous pouvez simplementsleep "$1"
ou quelque chose danscountdown
.time=$1; shift
, et vous n'avez alors pas besoin de la syntaxe de découpage en tableau pour les paramètres de position. Mais oui, c'est beaucoup plus simple.ctrl-c
, il est probablement préférable d'essayerkill -INT
au lieu dekill -9
(ou du moins d'essayer-9
seulement après quelques secondes si le premier n'a pas abouti - cela donne au programme une chance de quitter proprement et de ne pas laisser de fichiers temporaires etc autour de)Puisque vous mentionnez
ping
dans votre exemple; cette commande a quelques options pour arrêter après un laps de temps spécifique:la source