Como executar um comando várias vezes, usando o shell bash?

134

Existe uma maneira de executar um comando (por exemplo, ps aux|grep someprocess ) para n vezes?

Algo como:

run -n 10  'ps aux|grep someprocess'

Eu quero usá-lo de forma interativa, por favor, não postar scripts.

Update: A razão pela qual estou perguntando isso é que eu trabalho em muitas máquinas e não quero importar todos os meus scripts adaptados, etc., para cada caixa para obter a mesma funcionalidade em cada máquina.

    
por mahatmanich 24.05.2011 / 17:55

9 respostas

173

Eu não acho que um comando ou shell embutido para isso exista, já que é um subconjunto trivial para o qual o loop do Bourne shell for é projetado e implementar um comando como este por si mesmo é, portanto, bastante simples.

Para iniciantes, você pode usar um falso for loop:

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

Ou de forma equivalente, de acordo com a sugestão de JimB, usando o Bash incorporado para gerar sequências:

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

Isso itera dez vezes executando command de cada vez - pode ser um canal ou uma série de comandos separados por ; ou && . Você pode usar a variável $i para saber em qual iteração você está.

Se você considera este one-liner um script e então por algum motivo não especificado (mas talvez válido) indesejável você pode implementá-lo como um comando, talvez algo assim em seu .bashrc (não testado):

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

Uso:

run 10 command

Exemplo:

run 5 echo 'Hello World!'
    
por 24.05.2011 / 17:57
29

ps aux | grep someprocess parece que você deseja assistir a alterações de um programa por um período fixo. Eduardo deu uma resposta que respondeu exatamente a sua pergunta, mas há uma alternativa: watch :

watch 'ps aux | grep someprocess'

Note que coloquei o comando entre aspas simples para evitar que o shell interprete o comando como "run watch ps aux" e canalize o resultado por meio de grep someprocess . Outra maneira de fazer o comando anterior seria:

watch ps aux \| grep someprocess

Por padrão, watch é atualizado a cada dois segundos, o que pode ser alterado usando a opção -n . Por exemplo, se quiser ter um intervalo de 1 segundo:

watch -n 1 'ps aux | grep someprocess'
    
por 26.05.2011 / 17:07
21

Apenas por diversão

pgrep ssh ;!!;!!;!!;!!;!!;!!
    
por 27.06.2012 / 15:04
14

Tente isto:

yes ls | head -n5 | bash

Isso requer que o comando seja executado em um sub-shell, uma pequena penalidade de desempenho. YMMV. Basicamente, você obtém o comando "yes" para repetir a string "ls" N vezes; enquanto "head -n5" terminou o loop em 5 repetições. O pipe final envia o comando para o shell de sua escolha.

Aliás,% de shells comocsh têm um comando repeat embutido. Você poderia usar isso para executar seu comando em um sub-shell bash!

    
por 31.01.2013 / 01:04
11

semelhante às respostas anteriores, mas não exige o loop for:

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

saída de pipe seq para xargs sem argumentos ou opções

    
por 18.11.2015 / 15:36
4

caminho POSIX

link

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

que, naturalmente, pode ser transformado em um único forro:

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

e parece ser o caminho mais portátil e, portanto, menos propenso a fazer com que você instale programas.

Os seguintes são menos portáteis:

  • cinta de expansão {1..10} : bash specific e geraria uma linha enorme se o argumento for grande
  • seq : GNU
  • yes : GNU

E se você se cansar da portabilidade, considere o GNU parallel :

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

que executa comandos em paralelo e tem muitas opções interessantes.

Veja também: link

    
por 15.06.2015 / 11:39
2

Uma implementação de "fish shell" da função run do @ eduardo-ivanec acima

function run
  set number $argv[1]
  for i in (seq $number)
    eval $argv[2..-1]
  end
end
    
por 05.10.2017 / 20:57
0

Isso seria 'watch' - deveria fazer parte de quase todos os sistemas unix usando procps

Você pode ver mudanças de fs ou movimentos interessantes em um sistema. Por exemplo,

watch "df -hP | grep /tmp" 

Basta colocar seus comandos como argumento (veja man watch )

    
por 20.06.2018 / 20:44
0

No macOS você pode usar o comando repeat .

repeat 10 ps aux | grep someprocess
    
por 26.11.2018 / 17:29