web-dev-qa-db-fra.com

Ré-exécuter continuellement une commande à la fin de Bash

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é.

60
user107012

Cela crée une boucle infinie, en exécutant command maintes et maintes fois.

while :
    do
        command
done
37
Dennis

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.

103
Paul

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 )

17
BlueSky

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.

7
Daniel Beck

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.

4
user723485

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.

  1. Entrez la commande dans le terminal une fois.
  2. Sélectionnez la commande incluant le caractère de nouvelle ligne avec la souris.
  3. Copiez la sélection en utilisant Ctrl-Inser ou en utilisant le menu contextuel (généralement accessible avec un clic droit).
  4. Utilisez Maj-Insérer pour coller autant de fois que vous le souhaitez pour exécuter la commande.

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.

0
jayadeepk