GNU/Linux >> Tutoriels Linux >  >> Linux

Comment puis-je boucler sur la sortie d'une commande shell ?

J'ai trouvé que vous pouvez le faire en utilisant simplement des guillemets :

while read -r proc; do
     #do work
done <<< "$(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)"

Cela enregistrera chaque ligne dans le tableau plutôt que chaque élément.


Jamais for boucle sur les résultats d'une commande shell si vous souhaitez la traiter ligne par ligne, sauf si vous modifiez la valeur du séparateur de champ interne $IFS à \n . C'est parce que les lignes feront l'objet d'un fractionnement de mots ce qui conduit aux résultats réels que vous voyez. C'est-à-dire si vous avez par exemple un fichier comme celui-ci :

foo bar
hello world

La boucle for suivante

for i in $(cat file); do
    echo "$i"
done

vous donne :

foo
bar
hello
world

Même si vous utilisez IFS='\n' les lignes peuvent toujours faire l'objet d'une extension de nom de fichier

Je recommande d'utiliser while + read à la place parce que read lit ligne par ligne.

De plus, j'utiliserais pgrep si vous recherchez des pid appartenant à un certain binaire. Cependant, puisque python peut apparaître comme différents binaires, comme python2.7 ou python3.4 Je suggère de passer -f à pgrep ce qui le fait rechercher toute la ligne de commande plutôt que de simplement rechercher des binaires appelés python . Mais cela trouvera également les processus qui ont été démarrés comme cat foo.py . Tu étais prévenu! A la fin vous pouvez affiner la regex passée à pgrep comme vous le souhaitez.

Exemple :

pgrep -f python | while read -r pid ; do
    echo "$pid"
done

ou si vous voulez aussi le nom du processus :

pgrep -af python | while read -r line ; do
    echo "$line"
done

Si vous voulez le nom du processus et le pid dans des variables distinctes :

pgrep -af python | while read -r pid cmd ; do
    echo "pid: $pid, cmd: $cmd"
done

Vous voyez, read offre un moyen flexible et stable de traiter la sortie d'une commande ligne par ligne.

Au fait, si vous préférez votre ps .. | grep ligne de commande sur pgrep utilisez la boucle suivante :

ps -ewo pid,etime,cmd | grep python | grep -v grep | grep -v sh \
  | while read -r pid etime cmd ; do
    echo "$pid $cmd $etime"
done

Notez comment j'ai changé l'ordre de etime et cmd . Ainsi pour pouvoir lire cmd , qui peut contenir des espaces, en une seule variable. Cela fonctionne car read décomposera la ligne en variables, autant de fois que vous avez spécifié de variables. La partie restante de la ligne - y compris éventuellement des espaces blancs - sera affectée à la dernière variable qui a été spécifiée dans la ligne de commande.


Lors de l'utilisation de for boucle dans bash, il divise la liste donnée par défaut par whitespaces , cela peut être adapté en utilisant le soi-disant séparateur de champ interne , ou IFS en bref .

IFS Le séparateur de champ interne qui est utilisé pour diviser les mots après expansion et pour diviser les lignes en mots avec la commande intégrée read. La valeur par défaut est "".

Pour votre exemple, nous aurions besoin de dire IFS utiliser new-lines comme point d'arrêt.

IFS=$'\n'

for tbl in $(ps -ewo pid,cmd,etime | grep python | grep -v grep | grep -v sh)
do
   echo $tbl
done

Cet exemple renvoie la sortie suivante sur ma machine.

  668 /usr/bin/python /usr/bin/ud    03:05:54
27892 python                            00:01

Linux
  1. Comment mettre en surbrillance un mot dans la sortie de "cat" ? ?

  2. Comment puis-je copier la sortie d'une commande directement dans mon presse-papiers ?

  3. Comment capturer la sortie d'une commande top dans un fichier sous Linux ?

  4. Comment puis-je trouver ma version de shell à l'aide d'une commande Linux ?

  5. Comment puis-je copier la sortie d'une commande à distance dans le presse-papiers local ?

Comment utiliser la commande Linux grep

Comment exécuter des commandes Shell via un serveur HTTP

Comment rediriger la sortie de la commande shell

Comment utiliser la commande su sur adb shell ?

Comment passer la sortie de la commande sous forme d'arguments multiples à une autre commande

Comment exécuter la commande Vim depuis le shell ?