De vez en cuando ejecuto una línea de comando bash como esta:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
Para ejecutar some_commandvarias veces seguidas, 10 veces en este caso.
A menudo some_commandes realmente una cadena de comandos o una tubería.
¿Hay una manera más concisa de hacer esto?

let ++nlugar den=$((n+1))(3 caracteres menos).zshtienerepeat 10 do some_command; done.sh: 1: [[: not found.Respuestas:
O como una línea para aquellos que quieren copiar y pegar fácilmente:
fuente
for (n=0;n<k;n++))puede ser mejor; Sospecho que{1..k}se materializará una cadena con todos esos enteros separados por espacios.n=15;for i in $(seq -f "%02g" ${n});do echo $i; done 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15Usando una constante:
Usando una variable (puede incluir expresiones matemáticas):
fuente
x=10for ((n=0; n < $x; n++));for run in {1..10}; do echo "on run $run"; donenpasa si ya está configurado en un valor específico?for (( ; n<10; n++ ))no funciona / editar: mejor utilizar probablemente una de las otras respuestas, como elwhile (( n++...unoOtra forma simple de hackearlo:
ejecutar echo 20 veces.
Observe que eso
seq 20 | xargs -Iz echo "Hi there z"generaría:fuente
seq 20)seq 20 | xargs -I{} echo "Hi there {}"zno es un buen marcador de posición porque es tan común que puede ser un texto normal en el texto del comando. El uso{}será mejor.seq? así que solo se imprimiríaHi there20 veces (sin número)? EDITAR: solo use-I{}y luego no tenga ninguno{}en el comandoIIIIIentonces se ve bien, por ejemplo:seq 20 | xargs -IIIIII timeout 10 yourCommandThatHangsSi está utilizando el shell zsh:
Donde 10 es el número de veces que se repetirá el comando.
fuente
repeat 10 { !! }Usando GNU Parallel puedes hacer:
Si no desea el número como argumento y solo ejecuta un trabajo a la vez:
Mire el video de introducción para una introducción rápida: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Recorra el tutorial ( http://www.gnu.org/software/parallel/parallel_tutorial.html ). Usted ordena línea con amor por ello.
fuente
-j1 -N0que a su vez fuera el paralelismo ????some_command1000 veces en serie sin argumentos? Y: ¿Puedes expresar eso más corto queparallel -j1 -N0 some_command ::: {1..1000}?repeat.sh repeatcount some_command. Para la implementación en el script de shell que podría usarparallel, si ya estuviera instalado en la máquina (probablemente no lo estaría). O podría gravitar hacia xargs ya que parece ser más rápido cuando no se necesita redireccionamientosome_command.parallel -N0 -j1 --retries 4 --results outputdir/ some_commandUna función simple en el archivo de configuración bash (a
~/.bashrcmenudo) podría funcionar bien.Llámalo así.
fuente
do ${*:2}, agregué evaldo eval ${*:2}para asegurarme de que funcionaría para ejecutar comandos que no comienzan con ejecutables. Por ejemplo, si desea establecer una variable de entorno antes de ejecutar un comando comoSOME_ENV=test echo 'test'.xargses rápido :En un moderno Linux de 64 bits, da:
Esto tiene sentido, ya que el
xargscomando es un proceso nativo único que genera el/usr/bin/truecomando varias veces, en lugar de los buclesforywhileque se interpretan en Bash. Por supuesto, esto solo funciona para un solo comando; Si necesita hacer múltiples comandos en cada iteración del ciclo, será tan rápido, o tal vez más rápido, que pasarsh -c 'command1; command2; ...'a xargsTambién
-P1podría cambiarse, por ejemplo,-P8para generar 8 procesos en paralelo para obtener otro gran impulso en la velocidad.No sé por qué GNU paralelo es tan lento. Pensé que sería comparable a los xargs.
fuente
Otra forma de tu ejemplo:
fuente
Por un lado, puede envolverlo en una función:
Llámalo como:
fuente
traquí es engañoso y está trabajando en la salida demanytimes, noecho. Creo que deberías eliminarlo de la muestra.xargs y seq ayudarán
la vista :
fuente
Tenga en cuenta el guión bajo en lugar de usar una variable.
fuente
_es un nombre variable.Si está bien haciéndolo periódicamente, puede ejecutar el siguiente comando para ejecutarlo cada 1 segundo indefinidamente. Puede colocar otras comprobaciones personalizadas para ejecutarlo n varias veces.
watch -n 1 some_commandSi desea tener una confirmación visual de los cambios, agregue
--differencesantes de lalscomando.Según la página del manual de OSX, también hay
La página de manual de Linux / Unix se puede encontrar aquí
fuente
Resolví con este bucle, donde repetir es un número entero que representa el número del bucle.
fuente
Otra respuesta más: use la expansión de parámetros en parámetros vacíos:
Probado en Centos 7 y MacOS.
fuente
Parece que todas las respuestas existentes requieren
bashy no funcionan con un BSD UNIX estándar/bin/sh(por ejemplo,kshen OpenBSD ).El siguiente código debería funcionar en cualquier BSD:
fuente
Un poco ingenuo, pero esto es lo que generalmente recuerdo de la cabeza:
Muy similar a la respuesta de @ joe-koberg. La suya es mejor, especialmente si necesita muchas repeticiones, pero es más difícil para mí recordar otra sintaxis porque en los últimos años no uso
bashmucho. No me refiero a las secuencias de comandos al menos.fuente
El archivo de script
y la salida a continuación
fuente
¿Qué tal la forma alternativa de las construcciones de bucle
formencionadas (bashref) ?fuente
Los bucles son probablemente la forma correcta de hacerlo, pero aquí hay una alternativa divertida:
echo -e {1..10}"\n" |xargs -n1 some_commandSi necesita el número de iteración como parámetro para su invocación, use:
echo -e {1..10}"\n" |xargs -I@ echo now I am running iteration @Editar: se comentó correctamente que la solución dada anteriormente funcionaría sin problemas solo con ejecuciones de comandos simples (sin tuberías, etc.). siempre puedes usar a
sh -cpara hacer cosas más complicadas, pero no vale la pena.Otro método que uso típicamente es la siguiente función:
rep() { s=$1;shift;e=$1;shift; for x in `seq $s $e`; do c=${@//@/$x};sh -c "$c"; done;}ahora puedes llamarlo como:
rep 3 10 echo iteration @Los primeros dos números dan el rango. El
@será traducido al número de iteración. Ahora también puedes usar esto con tuberías:rep 1 10 "ls R@/|wc -l"con darle el número de archivos en los directorios R1 .. R10.
fuente
rep 1 2 touch "foo @"no creará dos archivos "foo 1" y "foo 2"; más bien crea tres archivos "foo", "1" y "2". Puede haber una manera de acertar con la cita usandoprintfy%q, pero será complicado obtener una secuencia arbitraria de palabras correctamente citadas en una sola cadena para pasarsh -c.repen.bashrc, las invocaciones adicionales se vuelven mucho más concisas.