Est-ce que ps peut afficher uniquement les processus non-noyau sous Linux?

Réponses:

37

Cela devrait faire (sous Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) a PPID 0 ( sur Linux 2.6+ ) mais psne permet pas de filtrer pour PPID 0; donc ce work-around.

Hauke ​​Laging
la source
Bien, mais quelle est la garantie de kthreaddtoujours avoir le PID 2?
l0b0
@ l0b0 Je n'en ai aucune idée :-) Vous pouvez le faire en deux étapes: Déterminez le PID de kthreadd, puis créez l' psappel correspondant. Comment est-il garanti que cette chose sera "toujours" appelée "kthreadd"? Une solution sûre serait plus compliquée, fonctionner psnormalement et analyser la sortie, faire des tests peut-être.
Hauke ​​Laging
2
Dans Linux 2.4 au moins sur les architectures x86, ces processus avaient la ppid 1 et ne pouvaient donc pas être distingués de cette façon.
Stéphane Chazelas
1
être comme "ps -ef" do "ps --ppid 2 -p 2 --deselect -f" et le faire comme "ps aux" do "ps --ppid 2 -p 2 --deselect u"
Peter
1
@Totor j'ai vérifié et on dirait que c'est le xdrapeau qui ne fonctionne pas avec ça. ps au --ppid 2 -p 2 --deselectfonctionne bien.
Sankalp
9

Une façon de reconnaître les processus du noyau est de ne pas utiliser de mémoire utilisateur. Le champ vsz est donc 0. Cela permet également d'attraper les zombies (grâce à Stéphane Chazelas pour cette observation), qui peuvent être éliminés en fonction de leur statut.

ps axl | awk '$7 != 0 && $10 !~ "Z"'

Pour lister uniquement les PID:

ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
Gilles, arrête de faire le mal
la source
Comme ma solution, elle inclura également les processus zombies.
Stéphane Chazelas
1
@StephaneChazelas Bon point, j'ai ajouté une condition au filtre.
Gilles 'SO- arrête d'être méchant'
9

En pratique, je trouvais assez l'idiome suivant:

ps auxf | grep -v ]$

Il filtre les lignes se terminant par des crochets, ce qui peut entraîner l’omission d’entrées non souhaitées, mais il est très peu probable. En échange, il est assez facile à retenir et relativement rapide à taper.

Certains processus tels que avahi-daemon ajoutent entre parenthèses à leurs noms de processus (le nom d'hôte dans le cas d'avahi-daemon) et seront filtrés par cette commande.

onetom
la source
8

Une des particularités de ces processus est qu'ils ne sont pas sauvegardés par un fichier exécutable, vous pouvez donc le faire ( en zsh ):

ps /proc/[0-9]*/exe(^-@:h:t)

Ou avec n'importe quel shell POSIX:

ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"

C’est vérifier les processus qui /proc/<pid>/exesont un lien vers un fichier.

Mais cela signifie que vous devez être superutilisateur pour pouvoir vérifier l'état du /proc/<pid>/exelien symbolique.

Edit : Au fur et à mesure, les processus zombies remplissent (au moins) la même condition. Si vous ne voulez pas les exclure, vous devrez les rajouter. Comme:

ps -p "$(
  { find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
    ps -Ao pid=,state= | sed -n 's/ Z//p'
  } | paste -sd , -)"

Notez que ps -fles noms de processus entre crochets ne sont pas attribuables au fait qu’il s’agit de processus de noyau, mais parce qu’ils ont un caractère vide argv[](ps affiche donc le nom du processus au lieu d’ argv[0]ici). Vous pouvez avoir un processus d'espace utilisateur avec un vide argv[]aussi bien et vous pouvez avoir un nom de processus avec un argv[0]qui est de la forme [some-string]afin filtrer la pssortie en fonction de ces crochets ne sont pas une option à toute épreuve.

Stéphane Chazelas
la source
C'est une syntaxe de shell non standard, à mon avis.
Totor
1
@Totor, comme je l'ai dit, le premier est la zshsyntaxe. La seconde est la syntaxe standard POSIX sh(et pset findet cutet et paste). Bien sûr, /procn'est pas spécifié par POSIX.
Stéphane Chazelas
Accepter cette réponse parce que c'est universel (merci pour l'édition). Cependant, la réponse de Hauke ​​Laging est également très simple et agréable tant que vous ne traitez pas avec un noyau 2.4.
Totor
@Totor, la réponse de Hauke ​​présente également l'avantage de ne pas nécessiter le privilège de superutilisateur. Ma réponse fonctionne avec les noyaux 2.4 et 2.6 / 3, mais je suppose qu'il n'y a aucune garantie que cela fonctionne dans 4.x de toute façon.
Stéphane Chazelas
Hmm, vous avez raison, je n'ai pas pensé aux privilèges root. Cela peut entraîner des erreurs puisque vous obtenez toujours une réponse lorsque vous n'êtes pas root, mais c'est différent (vous devez donc être prudent lorsque vous les comptez, par exemple wc -l). Dans ce cas, je vais accepter la réponse de Hauke ​​Laging et vous donner un avis positif. ;)
Totor
1

Vous pouvez également simplement analyser la pssortie et rechercher des noms de processus qui ne sont pas entre crochets:

ps aux | awk '$NF!~/^\[.+\]$/'
terdon
la source
Un moyen un peu moins fiable d'obtenir la liste des utilisateurs qui vous intéressent: awk -F: '$7 ~ home { print $1 }' /etc/passwd- mais vous obtiendrez tout de même des processus mentionnant un tel nom d'utilisateur et vous laissant le fichier temporaire en suspens. Je retire mon vote négatif, mais uniquement parce que votre troisième solution est raisonnable.
Keith Thompson
Bah, vous avez raison, @KeithThompson, supprimez les autres, ils n'en valent pas la peine. Pourriez-vous m'aider à nettoyer les commentaires (maintenant) obsolètes?
terdon
2
Notez que $NFc'est le dernier mot de la ligne de commande dans la ps auxsortie. Les processus non-noyau peuvent [...]y avoir . Comme je l'ai dit dans ma réponse, la [xxx]notation ne vient pas du fait qu'il s'agit de processus du noyau, mais de l'absence de ligne de commande (pas d'argument), ce qui est également autorisé pour les processus non liés au noyau.
Stéphane Chazelas
1

Pour tous ceux qui essayent ceci dans busybox où la configuration psest simplifiée et la sortie est différente, cette variante de la réponse géniale de Gilles fonctionne bien:

ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'

Selon la réponse de Gilles, la méthodologie consiste à rechercher des processus qui n'utilisent pas de mémoire utilisateur (`vsz col == 0), et à filtrer les processus zombies (le statut du code n'est pas 'Z').

Les colonnes de sortie peuvent être facilement ajustées, à condition que les numéros de champs awk basés sur 1 soient ajustés en conséquence. Voyez les options disponibles pour votre ps en mettant une valeur fictive et elle vous le dira. Par exemple:

$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Russ
la source
0

Si vous n’avez besoin que des comptes ... J’avais le même besoin de filtrer les processus du noyau par rapport aux processus utilisateur, mais je n’avais besoin que des comptes respectifs de chacun. C'était ma solution:

ps -eo vsize | awk '{p[$1==0]++} END {printf "%-16s %6d\n%-16s %6d\n%-16s %6d\n", "Kernel processes", p[1], "User processes", p[0], "Total processes", p[0]+p[1]}'

Exemple de sortie :

Kernel processes    353
User processes       52
Total processes     405

Explication : J'utilise le piratage voulant que les processus VSZ = 0 puissent être considérés comme des processus du noyau. Donc avec awk, j’évalue une comparaison sur VSZ (de ps -eo vsize), si elle est égale à zéro. Le résultat de la comparaison sera un booléen 0 ou 1. Je crée un tableau p[]et, au fur et à mesure que je parcours la liste des processus, si c'est un processus du noyau, j'incrémente p[1]++. Sinon, en tant que processus utilisateur, j'incrémente p[0]++. Après tout l’incrémentation, j’étiquette et imprime les valeurs (c’est-à-dire les comptes) pour p [0] et p [1] dans le END { }bloc.

Joshua Huber
la source
0

Ce que vous cherchez, mon ami, n’est pas ps, mais pstree.

Commencez par identifier le premier processus du noyau. Son PID est généralement 1 sur un système sans systemd et 2 avec systemd.

Ensuite, utilisez cette commande:

$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'

La réponse sélectionnée (une avec) utilise une autre commande:

$ ps --ppid 2 -p 2 --deselect

Le problème avec cette pscommande est qu'elle n'inclut que les enfants directs, mais pas tous les descendants. La pstreecommande inclut tous les descendants. Vous pouvez comparer et compter le résultat de ces deux commandes (un moyen simple à utiliser | wc) à vérifier.

ssppjj
la source
0

J'ai créé un script psa à cette fin. Notez que cela dépend de l' outil linechop .

Tomáš Pospíšek
la source