Explication sur awk

koma_666 Messages postés 429 Date d'inscription   Statut Membre Dernière intervention   -  
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   -
Salut à tous,

je comprends mal le fonctionnement de awk, plus particulièrement pour cette commande qui permet de tuer l'ensemble des processus zombie :

ps -eaf | grep "defunct" | awk -F " " '{print "kill -9",$2}' | sh


Pas de soucis pour la 1ère partie de la commande (ps et grep). Par contre, plus de soucis pour la partie awk.

Vou sauriez quelques explications ?

merci d'avance

3 réponses

zipe31 Messages postés 36402 Date d'inscription   Statut Contributeur Dernière intervention   6 430
 
Salut,

@qqchquicommenceparQ
@mamiemando

Attention !!!

awk -F " " '/<defunct>/{print "kill -9",$2}'
retournera aussi le PID de "awk" ;-((
awk -F " " '/<def[u]nct>/{print "kill -9",$2}'
Ne retournera que les bons PID ;-)

Notez que le caractère entre "[.]" peut être n'importe lequel et même plusieurs ;-)
2
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   7 879
 
Ah oui pas bête l'astuce avec les [...] :-)
0
Utilisateur anonyme
 
salut,

le grep est inutile.
ps -eaf | awk -F " " '/defunct/{print "kill -9",$2}' | sh

mais, qu'est-ce tu ne comprends pas ?
c'est pourtant limpide : pour chaque ligne où "defunct" apparaît, awk imprime kill -9 et le deuxième champ, pour que sh exécute la commande.
0
mamiemando Messages postés 33769 Date d'inscription   Statut Modérateur Dernière intervention   7 879
 
Alors le mieux serait lire la doc de awk dans laquelle toute la syntaxe est expliquée ou sur wikipedia.

Concrètement awk raisonne sur un flux texte qu'il voit comme un ensemble de lignes décomposées en colonnes.

Un programme awk est composé de plusieurs blocs délimités par des accolades.
- un bloc BEGIN (lancé au début du traitement)
- un bloc END (lancé à la fin du traitement)
- et plein de blocs (lancés à chaque lecture de ligne), précédés d'une condition (par exemple une expression régulière).

Dans ton cas tu n'as ni bloc BEGIN, ni END, juste un bloc qui n'est soumis à aucune condition et qui sera donc invoqué à chaque fois qu'une ligne est lue.

L'option -F permet de spécifier le délimiteur de colonne, en l'occurrence le caractère " ". À chaque fois que awk lit une ligne, il stocke le contenu des cellules dans des variables ($1 première cellule, $2 deuxième cellule etc...). $0 regroupe toute la ligne. En l'occurrence on voit que tu récupères la deuxième cellule (ce qui correspond à la colonne des PID dans la commande ps).

Ici awk va donc mouliner chaque ligne renvoyée par la chaîne ps -eaf | grep "defunct" et la remettre sous la forme "kill -9 xxx" ou xxx est un PID de zombi. Ceci est une commande shell et il va falloir l'exécuter. C'est ce qui est fait avec la dernière partie de la chaîne (| sh).

Bon c'est pas top top top :
- on risque de voir le processus grep defunct et de le tuer
- si un processus s'appelle defunct ou prend un paramètre qui est defunct (comme c'est le cas de ton grep) il sera également tué.

Concrètement le grep pour être supprimé au profit d'une expression régulière qui serait traitée par awk. En awk, une expression régulière s'écrit entre /.../. De ce que j'en vois on pourrait même chercher le motif "<defunct>" et non "defunct". À vue de nez ça pourrait être :

ps -eaf | awk -F " " '/<defunct>/{print "kill -9",$2}' | sh


Bonne chance
0