Hay una mejor manera de ejecutar un comando N veces en bash?
Ocasionalmente corro una línea de comandos bash como esta:
n=0; while [[ $n -lt 10 ]]; do some_command; n=$((n+1)); done
Para ejecutar some_command
varias veces seguidas 1 10 veces en este caso.
A menudo some_command
es realmente una cadena de comandos o una canalización.
¿Hay una manera más concisa de hacer esto?
19 answers
for run in {1..10}
do
command
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-17 18:01:50
for ((n=0;n<10;n++)); do some_command; done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-17 18:01:27
Otra forma sencilla de hackearlo:
seq 20 | xargs -Iz echo "Hi there"
Ejecuta echo 20 veces.
Observe que seq 20 | xargs -Iz echo "Hi there z"
produciría:
Hola 1
Hola 2
...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-27 22:21:57
Si estás usando el shell zsh:
repeat 10 { echo 'Hello' }
Donde 10 es el número de veces que se repetirá el comando.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-29 12:42:20
Usando GNU Parallel puedes hacer:
parallel some_command ::: {1..1000}
Si no desea el número como argumento y solo ejecuta un solo trabajo a la vez:
parallel -j1 -N0 some_command ::: {1..1000}
Vea el video de introducción para una introducción rápida: https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1
Recorre el tutorial ( http://www.gnu.org/software/parallel/parallel_tutorial.html ). Usted línea de comandos con amor por ello.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-01-17 22:20:20
Otra forma de tu ejemplo:
n=0; while (( n++ < 10 )); do some_command; done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-17 19:06:28
xargs
es rápido :
#!/usr/bin/bash
echo "while loop:"
n=0; time while (( n++ < 10000 )); do /usr/bin/true ; done
echo -e "\nfor loop:"
time for ((n=0;n<10000;n++)); do /usr/bin/true ; done
echo -e "\nseq,xargs:"
time seq 10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nyes,xargs:"
time yes x | head -n10000 | xargs -I{} -P1 -n1 /usr/bin/true
echo -e "\nparallel:"
time parallel --will-cite -j1 -N0 /usr/bin/true ::: {1..10000}
En un Linux moderno de 64 bits, da:
while loop:
real 0m2.282s
user 0m0.177s
sys 0m0.413s
for loop:
real 0m2.559s
user 0m0.393s
sys 0m0.500s
seq,xargs:
real 0m1.728s
user 0m0.013s
sys 0m0.217s
yes,xargs:
real 0m1.723s
user 0m0.013s
sys 0m0.223s
parallel:
real 0m26.271s
user 0m4.943s
sys 0m3.533s
Esto tiene sentido, ya que el comando xargs
es un único proceso nativo que genera el comando /usr/bin/true
varias veces, en lugar de los bucles for
y while
que se interpretan en Bash. Por supuesto, esto solo funciona para un solo comando; si necesita hacer varios comandos en cada iteración del bucle, será igual de rápido, o tal vez más rápido, que pasar sh -c 'command1; command2; ...'
a xargs
El -P1
también se podría cambiar a, por ejemplo, -P8
para generar 8 procesos en paralelo para obtener otro gran impulso en la velocidad.
No entiendo por qué GNU parallel es tan lento. Habría pensado que sería comparable a Xargs.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-04-05 18:38:42
Una función simple en el archivo de configuración de bash (.bashrc para mí, en un Mac) podría funcionar bien.
function runx() {
for ((n=0;n<$1;n++))
do ${*:2}
done
}
Llámalo así.
$ runx 3 echo 'Hello world'
Hello world
Hello world
Hello world
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-29 14:52:30
Xargs y seq ayudarán
function __run_times { seq 1 $1| { shift; xargs -i -- "$@"; } }
La vista:
abon@abon:~$ __run_times 3 echo hello world
hello world
hello world
hello world
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-01-26 16:21:02
for _ in {1..10}; do command; done
Tenga en cuenta el subrayado en lugar de usar una variable.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-11-12 23:04:11
Para uno, puede envolverlo en una función:
function manytimes {
n=0
times=$1
shift
while [[ $n -lt $times ]]; do
$@
n=$((n+1))
done
}
Llámalo como:
$ manytimes 3 echo "test" | tr 'e' 'E'
tEst
tEst
tEst
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-17 18:06:27
Si está bien hacerlo periódicamente, puede ejecutar el siguiente comando para ejecutarlo cada 1 segundo indefinidamente. Puede poner otras comprobaciones personalizadas en su lugar para ejecutarlo n número de veces.
watch -n 1 some_command
Si desea tener confirmación visual de los cambios, añada --differences
antes del comando ls
.
De acuerdo con la página man de OSX, también hay
La opción cumulative cumulative hace que el resaltado sea "pegajoso", presentando un visualización de todas las posiciones que tienen nunca cambió. The-t o la opción no no-title desactiva el encabezado que muestra el intervalo, comando, y la hora actual en la parte superior de la pantalla, así como siguiendo una línea en blanco.
La página de manual de Linux/Unix se puede encontrar aquí
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-11-07 08:42:40
Todas las respuestas parecen exigir bash
, y no trabajar con un estándar de BSD UNIX /bin/sh
(por ejemplo,, ksh
en OpenBSD).
El siguiente código debería funcionar en cualquier BSD:
$ echo {1..4}
{1..4}
$ seq 4
sh: seq: not found
$ for i in $(jot 4); do echo e$i; done
e1
e2
e3
e4
$
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-23 04:54:55
Otra respuesta: Usar expansión de parámetros en parámetros vacíos:
# calls curl 4 times
curl -s -w "\n" -X GET "http:{,,,}//www.google.com"
Probado en Centos 7 y macOS.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-17 22:21:48
Resolví con este bucle, donde repeat es un entero que representa el número de los bucles
repeat=10
for n in $(seq $repeat);
do
command1
command2
done
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-19 11:03:17
¿Qué tal la forma alternativa de for
mencionada en (bashref)Construcciones de bucle?
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-17 18:02:34
Los bucles For son probablemente la forma correcta de hacerlo, pero aquí hay una alternativa divertida:
echo -e {1..10}"\n" |xargs -n1 some_command
Si 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 @
Edit: Se comentó con razón que la solución dada anteriormente solo funcionaría sin problemas con simples ejecuciones de comandos (sin tuberías, etc.).). siempre puedes usar un sh -c
para hacer cosas más complicadas, pero no vale la pena.
Otro método que uso normalmente es el 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 dos primeros números dan el rango. El @
se traducirá 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.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-09-16 13:51:31
El archivo de script
bash-3.2$ cat test.sh
#!/bin/bash
echo "The argument is arg: $1"
for ((n=0;n<$1;n++));
do
echo "Hi"
done
Y la salida siguiente
bash-3.2$ ./test.sh 3
The argument is arg: 3
Hi
Hi
Hi
bash-3.2$
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-02-10 16:45:10
Un poco ingenuo, pero esto es lo que generalmente recuerdo de la parte superior de mi cabeza:
for i in 1 2 3; do
some commands
done
Muy similar a la respuesta de @joe-koberg. La suya es mejor, especialmente si necesita muchas repeticiones, solo que es más difícil para mí recordar otra sintaxis porque en los últimos años no estoy usando bash
mucho. Quiero decir, no para escribir al menos.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-06 13:43:36