Esiste uno strumento UNIX standard per ripetere un comando un numero di volte?


13

Questo è probabilmente estremamente semplice, ma esiste un modo semplice per scrivere un comando una volta nella console e farlo eseguire nvolte, dove nviene specificato in fase di esecuzione? Qualcosa come questo:

repeat 100 echo hello

Esiste un comando del genere (si supponga un'installazione tipica di Linux)?

O scriverei per fare una specie di loop in bash?

Risposte:


23

Sì questo è possibile. Bash ha un linguaggio di scripting molto esteso. In questo caso:

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

Altri esempi di loop: http://www.cyberciti.biz/faq/bash-for-loop/
Riferimento completo bash: http://www.gnu.org/software/bash/manual/bashref.html


cosa succede quando il comando fallisce?
Maazza,

La tua gestione degli errori lo rileva e scopre cosa fare.
Xyon,

Ho provato for i in {1..100}; do python3 foo.py ; donee in realtà intendo ottenere il tempo di esecuzione (per vedere quanto velocemente) time for i in {1..100}; do python3 foo.py ; donee quindi CTRL-C non sarà in grado di fermare il ciclo
nonopolarità

3

O scriverei per fare una specie di loop in bash?

Sì, in questo modo:

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

o, più breve:

for((i=100;i--;)); do echo "hello"; done

e poi metti quella roba in una funzione e voilà, hai il tuo comando: repeat () {for_stuff_here; fai "$ @"; done}
Akira,

3

Oltre ai metodi più integrati, è possibile utilizzare un'utilità esterna che genera una sequenza di numeri.

# 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

3

La sintassi del ciclo for è sciocca. Questo è più breve:

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

2

Non ho trovato uno strumento Linux "standard" per fare questo lavoro, ma di solito conservo i miei file dot (.bashrc, .vimrc ecc.) Dall'installazione all'installazione, quindi il seguente è piuttosto "standard" se lo guardi da la prospettiva di preservare i file dot in nuove installazioni:

Alla fine di .bashrc o .bash_aliases, inserisci la seguente definizione:

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
}

Salvare il file e riaprire la shell o eseguire source /path/to/.bashrco source /path/to/.bash_aliases, a seconda di quale si sceglie di modificare, in una shell esistente.

Questo è tutto! Dovresti essere in grado di usarlo nel modo seguente:

repeat 100 echo hello

repeat 84 ~/scripts/potato.sh

eccetera.


simpatico. sarebbe bene mettere "local" davanti a n = $ 1, per evitare di inquinare lo spazio dei nomi delle variabili globali
Don Hatch,

0

Attualmente, nessuna delle altre risposte utilizza strumenti Unix standard, che è ciò che la domanda sul titolo richiede.

Usano tutti comandi non standard ( seqo jot) o estensioni di shell ( forloop in stile C o espansione di parentesi graffe), ovvero non riescono a rispettare lo standard POSIX.

Ecco un modo portatile che dovrebbe funzionare con qualsiasi shell e sistema operativo compatibili con POSIX:

for i in $(awk 'BEGIN {for(i=0;i<100;i++) print i}'); do echo hello; done
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.