Répéter une commande tous les x intervalles de temps dans le terminal?

120

Comment puis-je répéter une commande à chaque intervalle de temps, de manière à pouvoir exécuter des commandes pour vérifier ou surveiller les répertoires?

Il n’ya pas besoin de script, j’ai juste besoin d’une simple commande à exécuter dans le terminal.

    
posée muru 06.03.2014 - 16:52
la source

8 réponses

185

Vous pouvez utiliser la commande watch , regarder est utilisé pour exécuter n'importe quelle commande à intervalles réguliers.

Ouvrez Terminal et tapez:

watch -n x <your command>

modifiez x pour afficher l’heure souhaitée en secondes.

Pour plus d’aide sur l’utilisation de la commande watch et de ses options, exécutez man watch ou visitez ce lien .

Par exemple: la liste suivante répertorie, tous les 60s , sur le même terminal, le contenu du répertoire Desktop afin de savoir si des modifications ont été apportées:

watch -n 60 ls -l ~/Desktop
    
réponse donnée nux 06.03.2014 - 16:54
la source
74

Vous pouvez aussi utiliser cette commande dans le terminal, à part la réponse de nux:

while true; do <your_command>; sleep <interval_in_seconds>; done

Exemple

while true; do ls; sleep 2; done

Cette commande imprimera les résultats de ls à un intervalle de 2 secondes.

Utilisez Ctrl + C pour arrêter le processus.

Il y a peu d'inconvénients de watch

  • Il ne peut utiliser aucune commande aliasée.
  • Si la sortie d’une commande est assez longue, le défilement ne fonctionne pas correctement.
  • Il est difficile de définir l’intervalle de temps maximal au-delà d’une certaine valeur.
  • watch interprétera les séquences de couleurs ANSI en passant les caractères d'échappement en utilisant l'option -c ou --color . Par exemple, la sortie de pygmentize fonctionnera mais elle échouera pour ls --color=auto .

Dans les circonstances ci-dessus, cela peut apparaître comme une meilleure option.

    
réponse donnée souravc 06.03.2014 - 17:00
la source
31

Je voulais juste parler de souravc et nux :

  1. Alors que watch fonctionnera parfaitement sur Ubuntu, vous voudrez peut-être éviter que si vous voulez que votre "Unix-fu" soit pur - sur FreeBSD par exemple, watch soit une commande pour "espionner une autre ligne tty".
  2. while true; do command; sleep SECONDS; done a également une réserve - votre commande peut être plus difficile à tuer en utilisant CTR + C . Vous voudrez peut-être préférer while sleep SECONDS; do command; done - non seulement plus court, mais aussi plus facile à interrompre. La mise en garde est qu'il va d'abord dormir, puis exécutez votre commande, de sorte que vous devrez attendre SECONDS avant que la première occurrence de la commande se produise.
réponse donnée d33tah 08.03.2014 - 16:51
la source
11

Cela semble être la tâche idéale pour le démon cron qui permet d'exécuter des commandes périodiques. Exécutez la commande crontab -e pour commencer la modification de la configuration cron de votre utilisateur. Son format est documenté dans crontab (5) . Fondamentalement, vous avez cinq champs séparés par un espace, suivis d'une commande:

The time and date fields are:

       field          allowed values
       -----          --------------
       minute         0-59
       hour           0-23
       day of month   1-31
       month          1-12 (or names, see below)
       day of week    0-7 (0 or 7 is Sunday, or use names)

Par exemple, si vous souhaitez exécuter un script Python tous les mardis à 11h00:

0 11 * * 1 python ~/yourscript.py

Il existe également des noms spéciaux qui remplacent l’heure, comme @reboot . Très utile si vous avez besoin de créer un répertoire temporaire. De mon crontab (répertorié avec crontab -l ):

# Creates a temporary directory for ~/.distcc at boot
@reboot ln -sfn "$(mktemp -d "/tmp/distcc.XXXXXXXX")" "$HOME/.distcc"
    
réponse donnée Lekensteyn 07.03.2014 - 19:54
la source
4

Si vous surveillez le système de fichiers, inotifywait est génial et ajoute certainement moins de charge à votre système.

Exemple:

Dans le 1er terminal, tapez cette commande:

$ inotifywait .

Ensuite, dans le terminal 2nd , toute commande affectant le répertoire en cours,

$ touch newfile

Ensuite, dans le terminal d'origine, inotifywait va se réveiller et signaler l'événement

./ CREATE newfile2

Ou en boucle

$ while true ; do inotifywait . ; done
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ OPEN newfile2
Setting up watches.  
Watches established.
./ DELETE newfile
Setting up watches.  
Watches established.
./ CREATE,ISDIR newdir
Setting up watches.  
Watches established.
    
réponse donnée X Tian 06.03.2014 - 17:35
la source
4

Vous pouvez créer votre propre commande repeat en procédant comme suit: crédits ici :

Tout d’abord, ouvrez votre fichier .bash_aliases :

$ xdg-open ~/.bash-aliases

Ensuite, collez ces lignes au bas du fichier et enregistrez:

repeat() {
n=
shift
while [ $(( n -= 1 )) -ge 0 ]
do
    "[email protected]"
done
}

Troisièmement, fermez et rouvrez votre terminal ou tapez:

$ source ~/.bash_aliases

Et voilà! Vous pouvez maintenant l'utiliser comme ceci:

$ repeat 5 echo Hello World !!!

ou

$ repeat 5 ./myscript.sh
    
réponse donnée Blufter 08.08.2014 - 21:38
la source
4

vous pouvez utiliser crontab. exécutez la commande crontab -e et ouvrez-la avec votre éditeur de texte préféré, puis ajoutez cette ligne

*/10 * * * *  /path-to-your-command

Cela exécutera votre commande toutes les 10 minutes

* */4 * * *  /path-to-your-command

Cela exécutera votre commande toutes les 4 heures

Autre solution possible

$ ..some command...; for i in $(seq X); do $cmd; sleep Y; done

X nombre de fois à répéter.

Y il est temps d’attendre pour répéter.

Exemple:

$ echo; for i in $(seq 5); do $cmd "This is echo number: $i"; sleep 1;done
    
réponse donnée Maythux 07.03.2014 - 06:57
la source
1

Une autre préoccupation avec l'approche "watch" proposée ci-dessus est qu'elle affiche le résultat uniquement lorsque le processus est terminé. "date; sleep 58; date" affichera les 2 dates seulement après 59 secondes ... Si vous démarrez quelque chose pendant 4 minutes, qui affichent lentement plusieurs pages de contenu, vous ne le verrez pas vraiment.

D'autre part, le problème avec l'approche "while" est qu'il ne prend pas en compte la durée de la tâche.

while true; do script_that_take_between_10s_to_50s.sh; sleep 50; done

Avec cela, le script s'exécutera parfois toutes les minutes, parfois il faudra 1m40. Donc, même si un cron peut l’exécuter toutes les minutes, ici ce ne sera pas le cas.

Donc, pour voir le résultat sur le shell tel qu'il est généré et attendre l'heure exacte de la requête, vous devez regarder l'heure avant et après, et boucler avec le temps.

Quelque chose comme:

while ( true ); do
  echo Date starting 'date'
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))'
  echo Before waiting 'date'
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
  echo Done waiting 'date'
done

Cela va afficher ceci:

Comme vous pouvez le voir, la commande s'exécute toutes les minutes:

Date starting Mon Dec 14 15:49:34 EST 2015
Before waiting Mon Dec 14 15:49:52 EST 2015
Done waiting Mon Dec 14 15:50:34 EST 2015

Date starting Mon Dec 14 15:50:34 EST 2015
Before waiting Mon Dec 14 15:50:39 EST 2015
Done waiting Mon Dec 14 15:51:34 EST 2015

Il suffit donc de remplacer la commande "sleep echo $(( ( RANDOM % 30 ) + 1 )) " par ce que vous voulez et qui sera exécuté, sur le terminal / shell, exactement à chaque minute. Si vous voulez un autre programme, changez simplement les "60" secondes avec tout ce dont vous avez besoin.

Version plus courte sans les lignes de débogage:

while ( true ); do
  before='date +%s'
  sleep 'echo $(( ( RANDOM % 30 )  + 1 ))' # Place you command here
  after='date +%s'
  DELAY='echo "60-($after-$before)" | bc'
  sleep $DELAY
done
    
réponse donnée jmspaggi 14.12.2015 - 21:56
la source

Lire d'autres questions sur les étiquettes