J'essaie de trouver un moyen simple de continuer à réexécuter une commande chaque fois qu'elle se termine, pour une raison quelconque (erreur ou autre).
Quelle serait la meilleure façon d'aborder cela?
EDIT: Je n'étais pas assez clair avant. J'ai besoin de la prochaine exécution pour attendez jusqu'à la fin de la précédente.
EDIT 2: Presque toutes les réponses fonctionnent très bien. Je pensais à tort que la plupart des réponses déboucheraient sur le processus ou le ré-exécuter une seule fois, ce qui n’est ni souhaité.
Cela crée une boucle infinie, en exécutant command
maintes et maintes fois.
while :
do
command
done
La commande watch
répétera une commande pour toujours avec un intervalle spécifié:
watch -n0 <command>
Régler -n
à zéro met effectivement l'intervalle à zéro (je pense que c'est vraiment 0,1 secondes).
watch
présente également l'avantage supplémentaire d'aligner la sortie afin que les modifications visuelles soient visibles, et dispose d'un commutateur pour mettre en surbrillance les modifications depuis la dernière exécution.
Référence: la page de manuel de watch :
watch run commande à plusieurs reprises, en affichant sa sortie (le premier écran). Cela vous permet de regarder l'évolution de la sortie du programme au fil du temps. Par défaut, le programme est exécuté toutes les 2 secondes. utilisez -n ou --interval pour spécifier un intervalle différent.
la montre fonctionnera jusqu'à ce qu'elle soit interrompue.
Une solution simple serait:
yourcommand; !#
;
sépare les commandes, permettant ainsi plusieurs commandes sur une seule ligne ( Bash: Lists )
!#
dit à bash de "répéter tout ce que j'ai écrit jusqu'à présent dans cette ligne" ( Bash: Event-Designators )
Vous pouvez planifier à l'avance pendant l'exécution de la commande (à condition que ce ne soit pas interactif) et entrer !!
qui exécutera à nouveau la commande précédente. Cela fonctionne par exemple pendant ping -c 5
.
Vous pouvez également définir une fonction dans bash
:
function repeat { "$@"; "$@"; }
Pour le persister, stockez-le dans ~/.bashrc
.
Ensuite, vous pouvez exécuter votre commande comme ceci:
repeat ping -c5 heise.de
S'il s'agit d'une commande spécifique que vous souhaitez exécuter de manière répétée (et non pas, par exemple, any command), vous pouvez remplacer "$@"
dans cet extrait par votre commande réelle et nommer la fonction, par exemple. repeat_ping
à la place.
Pour en faire une boucle infinie, vous pouvez faire ce que @Dennis suggère. Je vous recommande d’ajouter une période d’attente si vous avez l’intention de l’utiliser dans un shell interactif, comme ceci:
function repeat { while 1 ; do "$@" ; sleep 1 ; done; }
Sinon, il est plutôt gênant d’abandonner cette boucle infinie en utilisant Ctrl-Z
.
Attribuez à une boucle while
une condition booléenne, comme suit:
#!/bin/bash
while true; do
do_something && wait
done
Cela s'exécutera encore et encore jusqu'à ce que bash reçoive un signal signalant la fin du processus. Habituellement sous la forme de ctrl+c
.
Vous pouvez également utiliser la commande watch
pour exécuter un script à plusieurs reprises. Par exemple, une simple horloge dans votre terminal bash utilisant watch
pourrait ressembler à:
$ watch -t -n1 date +%T
L'option -t
indique à watch
de ne pas afficher le titre du processus en cours d'exécution. Cela vous donne une sortie propre de seulement la commande qui est répétée. L'option -n1
indique à la surveillance de répéter chaque n
secondes. Dans ce cas, -n1
sera des intervalles de 1
seconde. Ensuite, la commande date +%T
indique l'heure à laquelle la commande est terminée. Cette commande vous donnera une horloge active dans votre terminal.
Et puis une autre méthode qui ne figure dans aucune des autres réponses serait un appel de fonction infini.
do_something() { do_something }; do_something && wait
Ceci est essentiellement identique à la boucle booléenne while
utilisant uniquement des appels de fonction récursifs.
(edit) Pour garder les ressources de votre machine à l'esprit, j'ai ajouté le && wait
afin qu'à chaque exécution d'un processus, les boucles "attendent" que le processus se termine avec le statut de sortie 0 avant la prochaine itération. Ceci est utile dans un script shell interactif.
C'est une autre méthode que j'utilise pour répéter une commande dans bash. Cela peut sembler ridicule à certains car il ne s’agit pas d’écrire un script et peut être connu de beaucoup. Mais je pense que cela vaut la peine d’être mentionné car c’est rapide et adapté aux débutants, en ce sens qu’il n’ya pas beaucoup de syntaxe à retenir. Je n'ai testé cela que dans gnome-terminal d'Ubuntu et d'autres terminaux pourraient ne pas le supporter.
Vous n'avez pas à attendre pour coller jusqu'à ce que chaque commande se termine. Les commandes collées entrent dans une file d'attente et s'exécutent les unes après les autres.