Question Comment exécuter une commande plusieurs fois en utilisant le shell bash?


Existe-t-il un moyen d’exécuter une commande (par exemple, ps aux|grep someprocess) pour n fois?

Quelque chose comme:

run -n 10  'ps aux|grep someprocess'

Je veux l'utiliser de manière interactive, veuillez ne pas poster de scripts.

Mise à jour: La raison pour laquelle je pose cette question est que je travaille sur de nombreuses machines et que je ne souhaite pas importer tous les scripts adaptés, etc., dans chaque boîte pour que les mêmes fonctionnalités soient appliquées à toutes les machines.


132
2018-05-24 15:55


origine


Merveilleux que la réponse reçoive autant de votes positifs sans que la question n'en reçoive un. Changeons cela +1 :) - Lekensteyn
@Lekensteyn merci - mahatmanich
stackoverflow.com/questions/3737740/… - Ciro Santilli 新疆改造中心 六四事件 法轮功


Réponses:


Je ne pense pas qu'il existe une commande ou un shell pour cela, car c'est un sous-ensemble trivial de ce que le shell Bourne for loop est conçu pour implémenter une commande comme celle-ci est donc assez simple.

Pour commencer, vous pouvez utiliser un mannequin for boucle:

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

Ou de manière équivalente à la suggestion de JimB, en utilisant le Bash intégré pour générer des séquences:

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

Cette itère dix fois en exécutant command chaque fois - il peut s'agir d'un tuyau ou d'une série de commandes séparées par ; ou &&. Vous pouvez utiliser le $i variable pour savoir à quelle itération vous appartenez.

Si vous considérez cela comme un script et que, pour une raison non spécifiée (mais peut-être valide), vous pouvez l'implémenter en tant que commande, par exemple, sur votre .bashrc (non testé):

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

Usage:

run 10 command

Exemple:

run 5 echo 'Hello World!'

170
2018-05-24 15:57



@mahatmanich, une boucle n'est pas un script. Rien ne vous empêche d’utiliser pour ... sur un terminal interactif. - Zoredache
Eh bien, le modèle ci-dessus est le type de méthode standard pour le faire et il est assez simple. Pourquoi n'est-ce pas bon pour toi? Peut-être que vous posez la mauvaise question? Quel est le but principal de vos scripts ou de vos actions que vous souhaitez répéter plusieurs fois? Peut-être y a-t-il une meilleure solution si nous posons le problème différemment. - Patkos Csaba
@mahatmanich - for  est le bash intégré pour itérer. - JimB
@ Eduardo Ivanec - Pour votre information, bash a une gamme intégrée comme seq: {1..10} - JimB
Il semble que la séquence de crochets intégrée ne supporte pas la substitution de variable (voir stackoverflow.com/a/3737773/713554). La fonction que vous avez donnée fonctionne parfaitement lorsqu'elle est placée dans .bashrc si {1..$number} est échangé contre `seq $number` bien que. - Leo


ps aux | grep someprocess on dirait que vous voulez regarder les changements d'un programme pendant un temps fixe. Eduardo a donné une réponse qui répond à votre question avec précision, mais il existe une alternative: watch:

watch 'ps aux | grep someprocess'

Notez que j’ai mis la commande entre guillemets pour éviter que le shell n’interprète la commande comme "exécutez watch ps aux" et dirige le résultat grep someprocess. Une autre façon de faire la commande précédente serait:

watch ps aux \| grep someprocess

Par défaut, watch rafraîchit toutes les deux secondes, cela peut être changé en utilisant le -n option. Par exemple, si vous voulez avoir un intervalle de 1 seconde:

watch -n 1 'ps aux | grep someprocess'

29
2018-05-26 15:07



Oui cela fonctionne comme un charme. - Jānis Gruzis


Juste pour le fun

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

21
2018-06-27 13:04



Quelqu'un peut-il expliquer cela s'il vous plaît? Semble très intrigant. - Daniel Vartanov
; est juste un séparateur de commande. !! rejouer la dernière commande dans bash. Donc, lancez 'pgrep ssh' et rejouez-le 6 fois. - Piotr Kukielka
Bien que ce soit instructif, ce n’est pas très intuitif. Bon mot for semble le meilleur moyen. En tout cas merci pour la réponse. - erm3nda
Habitude cmd ;!! sur une ligne il suffit de répéter la commande entrée avant la ligne actuelle? Il faudrait deux séparés history les entrées. - Joel Purra


Essaye ça:

yes ls | head -n5 | bash

Cela nécessite que la commande soit exécutée dans un sous-shell, ce qui représente un léger inconvénient pour les performances. YMMV. En gros, vous obtenez la commande "oui" pour répéter la chaîne "ls" N fois; tandis que "head -n5" termine la boucle à 5 répétitions. Le dernier canal envoie la commande au shell de votre choix.

Incidemment cshcoquilles semblables à un intégré repeat commander. Vous pouvez l'utiliser pour exécuter votre commande dans un sous-shell bash!


14
2018-01-31 00:04





semblable aux réponses précédentes, mais ne nécessite pas la boucle for:

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

diriger la sortie de seq vers xargs sans arguments ni options


11
2017-11-18 14:36



Cela ne fera qu'une exécution echo "hello" 1 2 3 4 5 6 7 8 9 10. Vous devez exécuter xargs avec -n 1 pour un processus pour chaque entrée (nombre) et avec -P 10 pour une exécution parallèle (10 processus parallèles). Finir avec seq 10 | xargs -n 1 -P 10 echo. - Alexander Klimetschek


Manière 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

qui pourrait bien sûr être transformé en une ligne:

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

et semble être le moyen le plus portable, et donc moins susceptible de vous faire installer des programmes.

Les éléments suivants sont moins portables:

  • expansion du corset {1..10}: bash spécifique, et générerait une énorme ligne si l'argument est grand
  • seq: GNU
  • yes: GNU

Et si vous en avez assez de la portabilité, considérez GNU parallel:

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

qui exécute des commandes en parallèle et a de nombreuses options intéressantes.

Voir également: 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





Une implémentation de coquille de poisson de @ eduardo-ivanec run une fonction au dessus de

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

2
2018-06-20 18:44





Ce serait «regarder» - devrait faire partie de presque tous les systèmes Unix utilisant procps

Vous pouvez voir les changements de fs ou les mouvements intéressants dans un système. Par exemple,

watch "df -hP | grep /tmp" 

Il suffit de mettre vos commandes en argument (voir man watch)


0



Il y a déjà une réponse à regarder ... voir ci-dessous à droite ... - mahatmanich