Existe-t-il un outil UNIX standard pour répéter une commande un certain nombre de fois?

13

C'est probablement très simple, mais existe-t-il un moyen simple d'écrire une commande une fois dans la console et de l'exécuter nfois, où nest spécifié lors de l'exécution? Quelque chose comme ça:

repeat 100 echo hello

Existe-t-il une telle commande (supposez une installation Linux typique)?

Ou devrais-je écrire pour faire une sorte de boucle en bash?

Jørn Schou-Rode
la source

Réponses:

23

Oui c'est possible. Bash possède un langage de script très étendu. Dans ce cas:

for i in {1..100}; do echo 'hello'; done

Plus d'exemples de boucle: http://www.cyberciti.biz/faq/bash-for-loop/
Référence bash complète: http://www.gnu.org/software/bash/manual/bashref.html

alumb
la source
que se passe-t-il lorsque la commande échoue?
maazza
Votre gestion des erreurs l'attrape et détermine ce qu'il faut faire à la place.
Xyon
J'ai essayé for i in {1..100}; do python3 foo.py ; doneet je veux en fait obtenir le temps d'exécution (pour voir à quelle vitesse) time for i in {1..100}; do python3 foo.py ; done, puis CTRL-C ne pourra pas arrêter la boucle
non
3

Ou devrais-je écrire pour faire une sorte de boucle en bash?

Oui, vous aimeriez:

for(( i = 0; i < 100; i++ )); do echo "hello"; done

ou, plus court:

for((i=100;i--;)); do echo "hello"; done
Michael Borgwardt
la source
et puis mettez ce truc dans une fonction et le tour est joué, vous avez votre commande: repeat () {for_stuff_here; faire "$ @"; fait}
akira
3

En plus des méthodes plus intégrées, vous pouvez utiliser un utilitaire externe qui génère une séquence de nombres.

# gnu coreutils provides seq
for i in $(seq 1 100) ; do printf "hello\n" ; done

# freebsd (and probably other bsd) provides jot
for i in $(jot - 1 100) ; do printf "hello\n" ; done
phogg
la source
3

La syntaxe de la boucle for est idiote. C'est plus court:

seq 10|xargs -I INDEX echo "print this 10 times"
Pyrolistique
la source
2

Je n'ai pas trouvé d'outil Linux "standard" pour faire ce travail, mais je conserve généralement mes fichiers dot (.bashrc, .vimrc etc.) d'une installation à l'autre, donc ce qui suit est assez "standard" si vous le regardez depuis la perspective de conserver vos fichiers dot dans de nouvelles installations:

À la fin de votre .bashrc ou .bash_aliases, mettez la définition suivante:

repeat() {
  n=$1    #gets the number of times the succeeding command needs to be executed
  shift   #now $@ has the command that needs to be executed
  while [ $(( n -= 1 )) -ge 0 ]    #loop n times;
  do
    "$@"    #execute the command; you can also add error handling here or parallelize the commands
  done
}

Enregistrez le fichier et rouvrez le shell ou exécutez source /path/to/.bashrcou source /path/to/.bash_aliases, selon votre choix, dans un shell existant.

C'est ça! Vous devriez pouvoir l'utiliser de la manière suivante:

repeat 100 echo hello

repeat 84 ~/scripts/potato.sh

etc.

Rovin Bhandari
la source
agréable. il serait bon de mettre "local" devant le n = $ 1, pour éviter de polluer l'espace de noms des variables globales
Don Hatch
0

Actuellement, aucune des autres réponses n'utilise des outils Unix standard, ce que demande la question de titre.

Ils utilisent tous des commandes non standard ( seqou jot) ou des extensions de shell (extension de forboucle ou d'accolade de style C ), c'est-à-dire qu'ils ne respectent pas tous la norme POSIX.

Voici une méthode portable qui devrait fonctionner avec n'importe quel shell et système d'exploitation compatible POSIX:

for i in $(awk 'BEGIN {for(i=0;i<100;i++) print i}'); do echo hello; done
jlliagre
la source