Pregunta ¿Cómo ejecutar un comando varias veces, usando bash shell?


¿Hay una manera de ejecutar un comando (por ejemplo, ps aux|grep someprocess) para norte ¿veces?

Algo como:

run -n 10  'ps aux|grep someprocess'

Quiero usarlo de manera interactiva, por favor no publique scripts.

Actualización: la razón por la que pregunto esto es que trabajo en muchas máquinas y no quiero importar todos mis scripts adaptados, etc. en cada caja para obtener la misma funcionalidad en todas las máquinas.


132
2018-05-24 15:55


origen


Maravilloso que la respuesta obtenga tantos votos sin que la pregunta reciba uno. Vamos a cambiar ese +1 :) - Lekensteyn
@Lekensteyn gracias - mahatmanich
stackoverflow.com/questions/3737740/… - Ciro Santilli 新疆改造中心 六四事件 法轮功


Respuestas:


No creo que exista un comando o shell incorporado para esto, ya que es un subconjunto trivial de lo que el shell Bourne for loop está diseñado para implementar un comando como este, por lo tanto, es bastante simple.

Para empezar puedes usar un maniquí. for lazo:

for i in `seq 10`; do command; done

O, de manera equivalente, según la sugerencia de JimB, utilizando el componente Bash para generar secuencias:

for i in {1..10}; do command; done

Esto se repite diez veces ejecutando. command cada vez - puede ser una tubería o una serie de comandos separados por ; o &&. Puedes usar el $i Variable para saber en qué iteración estás.

Si considera este script de una sola línea y, por lo tanto, por alguna razón no especificada (pero quizás válida) no deseable, puede implementarlo como un comando, tal vez algo como esto en su .bashrc (no probado):

#function run
run() {
    number=$1
    shift
    for i in `seq $number`; do
      $@
    done
}

Uso:

run 10 command

Ejemplo:

run 5 echo 'Hello World!'

170
2018-05-24 15:57



@mahatmanich, un bucle no es un script. No hay nada que le impida utilizar para ... en un terminal interactivo. - Zoredache
Bueno, el de una sola línea anterior es el tipo de manera estándar de hacerlo y es bastante simple. ¿Por qué no es bueno para ti? Tal vez usted está haciendo la pregunta incorrecta? ¿Cuál es el objetivo principal de sus scripts o sus acciones que desea repetirlos varias veces? Tal vez haya una solución mejor si ponemos el problema de una manera diferente. - Patkos Csaba
@mahatmanich - for  es El bash incorporado para iterar. - JimB
@Eduardo Ivanec - FYI, bash tiene un rango incorporado como seq: {1..10} - JimB
Parece que la secuencia de corchetes incorporada no admite la sustitución de variables (ver stackoverflow.com/a/3737773/713554). La función que le diste funciona perfectamente cuando se coloca en .bashrc Si {1..$number} se intercambia por `seq $number` aunque. - Leo


ps aux | grep someprocess Parece que quieres ver los cambios de un programa por un tiempo fijo. Eduardo dio una respuesta que responde a su pregunta exactamente pero hay una alternativa: watch:

watch 'ps aux | grep someprocess'

Tenga en cuenta que he puesto el comando entre comillas simples para evitar que el shell interprete el comando como "ejecute watch ps aux" y canalice el resultado a través de grep someprocess. Otra forma de hacer el comando anterior sería:

watch ps aux \| grep someprocess

Por defecto, watch se actualiza cada dos segundos, que se puede cambiar utilizando el -n opción. Por ejemplo, si desea tener un intervalo de 1 segundo:

watch -n 1 'ps aux | grep someprocess'

29
2018-05-26 15:07



Sí, esto funciona como un encanto. - Jānis Gruzis


Solo por diversión

pgrep ssh ;!!;!!;!!;!!;!!;!!

21
2018-06-27 13:04



¿Puede alguien explicar esto, por favor? Parece muy intrigante. - Daniel Vartanov
; es solo comando separador. !! Repetir el último comando en bash. Entonces esto ejecuta 'pgrep ssh' y luego repítelo 6 veces. - Piotr Kukielka
Si bien eso es instructivo no es muy intuitivo. Un trazador de líneas for Parece la mejor manera. De todos modos gracias por la respuesta. - erm3nda
No lo hará cmd ;!! en una línea solo repita el comando ingresado antes de la linea actual? Tendría que ser dos separados history entradas. - Joel Purra


Prueba esto:

yes ls | head -n5 | bash

Esto requiere que el comando se ejecute en un sub-shell, una leve penalización de rendimiento. YMMV. Básicamente, obtienes el comando "sí" para repetir la cadena "ls" N veces; mientras que "head -n5" terminó el bucle en 5 repeticiones. La tubería final envía el comando al shell de su elección.

De paso csh-como las conchas tienen un incorporado repeat mando. ¡Puedes usar eso para ejecutar tu comando en un sub-shell de bash!


14
2018-01-31 00:04





similar a las respuestas anteriores, pero no requiere el bucle for:

seq 10 | xargs -I -- echo "hello"

Salida de tubería de seq a xargs sin argumentos ni opciones


11
2017-11-18 14:36



Esto solo hará una ejecución. echo "hello" 1 2 3 4 5 6 7 8 9 10. Necesitas ejecutar xargs con -n 1 para un proceso para cada entrada (número) y con -P 10 Para ejecución paralela (10 procesos paralelos). Terminando con seq 10 | xargs -n 1 -P 10 echo. - Alexander Klimetschek


Forma POSIX

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_06_04_01

x=10
while [ $x -gt 0 ]; do
    command
    x=$(($x-1))
done

que por supuesto se podría hacer en una sola línea:

x=10; while [ $x -gt 0 ]; do command; x=$(($x-1)); done

y parece ser la forma más portátil, y por lo tanto, es menos probable que te haga instalar programas.

Los siguientes son menos portátiles:

  • expansión de la abrazadera {1..10}: bash específico, y generaría una línea enorme si el argumento es grande
  • seq: GNU
  • yes: GNU

Y si te cansas de la portabilidad, considera GNU parallel:

sudo apt-get install parallel
seq 100 | parallel echo {}

que ejecuta comandos en paralelo y tiene muchas opciones geniales.

Ver también: https://stackoverflow.com/questions/169511/how-do-i-iterate-over-a-range-of-numbers-defined-by-variables-in-bash


4
2018-06-15 09:39





Implementación de una concha de pez de @ eduardo-ivanec's. run función encima

function run
  set number $argv[1]
  for i in (seq $number)
    eval $argv[2..-1]
  end
end

2
2018-06-20 18:44





Eso sería 'watch' - debería ser parte de casi todos los sistemas UNIX que utilizan procps

Puedes ver los cambios de fs o movimientos interesantes en un sistema. Por ejemplo,

watch "df -hP | grep /tmp" 

Solo ponga sus comandos como argumento (vea man watch)


0



Ya hay una respuesta con reloj ... ver abajo ... - mahatmanich