La timeout
commande GNU coreutils est extrêmement pratique pour certaines situations de script, permettant d'utiliser la sortie d'une commande si elle est rapide à exécuter et de la sauter si elle prendrait trop de temps.
Comment puis-je approximer le comportement de base de l' timeout
utilisation uniquement des utilitaires spécifiés POSIX?
(Je pense qu'il peut impliquer une combinaison de wait
, sleep
, kill
et qui sait quoi d' autre, mais peut - être que je manque une approche plus facile.)
shell-script
posix
timeout
Caractère générique
la source
la source
command & pid=$! ; sleep 5 && kill $pid
command
termine rapidement, il y a peu de chances d'pid
être réutilisé par un autre processus démarrant avant l'kill
exécution de la commande? Je ne voudrais pas cela dans le code de production ....timeout
programme et l'utiliser?Réponses:
Mon approche serait celle-ci:
Exécuter la commande comme processus d'arrière-plan 1
Exécutez le "temporisateur de surveillance" comme processus d'arrière-plan 2
Configurer un gestionnaire pour intercepter un signal de terminaison dans le shell parent
Attendez la fin des deux processus. Le processus qui se termine en premier, envoie le signal de terminaison au parent.
Le gestionnaire de pièges du parent tue les deux processus d'arrière-plan via le contrôle des tâches (l'un d'eux a déjà pris fin par définition, mais cette suppression sera une opération sans danger car nous n'utilisons pas de PID, voir ci-dessous)
J'ai essayé de contourner la condition de concurrence possible abordée dans les commentaires en utilisant les ID de contrôle des tâches du shell (qui seraient sans ambiguïté dans cette instance de shell) pour identifier les processus d'arrière-plan à tuer, au lieu des PID système.
Résultat pour
TIMEOUT=10
(la commande se termine avant le chien de garde):Résultat pour
TIMEOUT=1
(le chien de garde se termine avant la commande):Résultat pour
TIMEOUT=5
(le chien de garde et la commande se terminent "presque" simultanément):la source
cleanup() { ...; }
et (b) le contrôle des travaux est une fonctionnalité bash non spécifiée par POSIX (bien que ksh et d'autres l'aient également). Beau script, cependant!timeout="$1"; shift
et(exec "$@"; echo "Command completed"; kill $$)
plutôt que de réécrire la liste des arguments.