Gibt es ein Standard-UNIX-Tool, mit dem ein Befehl beliebig oft wiederholt werden kann?

13

Dies ist wahrscheinlich kinderleicht, aber gibt es eine einfache Möglichkeit, einen Befehl einmal in die Konsole zu schreiben und ihn nmal ausführen zu lassen , wo nzur Laufzeit angegeben? Etwas wie das:

repeat 100 echo hello

Existiert ein solcher Befehl (vorausgesetzt, eine typische Linux-Installation)?

Oder würde ich schreiben, um eine Art Schleife in Bash zu machen?

Jørn Schou-Rode
quelle

Antworten:

23

Ja das ist möglich. Bash hat eine sehr umfangreiche Skriptsprache. In diesem Fall:

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

Weitere Beispiele für Schleifen: http://www.cyberciti.biz/faq/bash-for-loop/
Vollständige Bash-Referenz: http://www.gnu.org/software/bash/manual/bashref.html

alumb
quelle
Was passiert, wenn der Befehl fehlschlägt?
Maazza
Ihre Fehlerbehandlung fängt es auf und ermittelt stattdessen, was zu tun ist.
Xyon
Ich habe versucht for i in {1..100}; do python3 foo.py ; doneund wollte eigentlich die Ausführungszeit ermitteln (um zu sehen, wie schnell), time for i in {1..100}; do python3 foo.py ; doneund dann kann STRG-C die Schleife nicht stoppen
Unpolarität
3

Oder würde ich schreiben, um eine Art Schleife in Bash zu machen?

Ja, das würde dir gefallen:

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

oder kürzer:

for((i=100;i--;)); do echo "hello"; done
Michael Borgwardt
quelle
und dann setzen Sie das Zeug in eine Funktion und voila, Sie haben Ihren Befehl: repeat () {for_stuff_here; mache "$ @"; erledigt}
Akira
3

Zusätzlich zu mehr integrierten Methoden können Sie ein externes Dienstprogramm verwenden, das eine Folge von Zahlen generiert.

# 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
quelle
3

Die for-Schleifensyntax ist albern. Das ist kürzer:

seq 10|xargs -I INDEX echo "print this 10 times"
Pyrolistisch
quelle
2

Ich habe kein "Standard" -Linux-Tool gefunden, um diesen Job zu erledigen, aber ich behalte normalerweise meine Punktedateien (.bashrc, .vimrc usw.) von Installation zu Installation bei, daher ist das Folgende ziemlich "Standard", wenn man es betrachtet die Perspektive, Ihre Punktedateien in neuen Installationen zu erhalten:

Geben Sie am Ende Ihrer .bashrc- oder .bash_aliases die folgende Definition ein:

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
}

Speichern Sie die Datei und öffnen Sie die Shell erneut oder führen Sie sie source /path/to/.bashrcoder source /path/to/.bash_aliases, je nachdem, was Sie ändern möchten, in einer vorhandenen Shell aus.

Das ist es! Sie sollten es auf folgende Weise verwenden können:

repeat 100 echo hello

repeat 84 ~/scripts/potato.sh

etc.

Rovin Bhandari
quelle
nett. Es wäre gut, "local" vor n = $ 1 zu setzen, um eine Verschmutzung des globalen Variablennamensraums zu vermeiden
Don Hatch,
0

Derzeit verwendet keine der anderen Antworten Standard-Unix-Tools, nach denen in der Titelfrage gefragt wird.

Sie alle verwenden entweder nicht standardmäßige Befehle ( seqoder jot) oder Shell-Erweiterungen ( forSchleifen- oder Klammererweiterung im C-Stil ), dh sie halten sich nicht an den POSIX-Standard.

Hier ist eine tragbare Methode, die mit jeder POSIX-kompatiblen Shell und jedem Betriebssystem funktionieren sollte:

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