Kann ps unter Linux nur Nicht-Kernel-Prozesse anzeigen?

Antworten:

37

Dies sollte (unter Linux) tun:

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) hat PPID 0 ( unter Linux 2.6+ ), pserlaubt jedoch kein Filtern nach PPID 0; also diese umgehung.

Hauke ​​Laging
quelle
Schön, aber wie garantiert ist es, dass kthreaddimmer PID 2 ist?
07.06.13
@ l0b0 Ich habe keine Ahnung :-) Du könntest das in zwei Schritten machen: Ermittle die PID von kthreadd, dann baue den entsprechenden psAufruf auf. Wie sicher ist es, dass dieses Ding "immer" "kthreadd" heißt? Eine sichere Lösung wäre komplizierter, würde psnormal ablaufen und die Ausgabe analysieren, möglicherweise einige Tests durchführen.
Hauke ​​Laging
2
Zumindest in Linux 2.4 auf x86 arch hatten diese Prozesse ppid 1 und konnten so nicht unterschieden werden.
Stéphane Chazelas
1
um wie "ps -ef" zu sein, mache "ps --ppid 2 -p 2 --deselect -f" und um es wie "ps aux" zu machen, mache "ps --ppid 2 -p 2 --deselect u"
Peter
1
@Totor Ich habe es überprüft und es sieht so aus, als ob es die xFlagge ist, die damit nicht funktioniert. ps au --ppid 2 -p 2 --deselectfunktioniert ok
Sankalp
9

Eine Möglichkeit, Kernel-Prozesse zu erkennen, besteht darin, dass sie keinen Benutzerspeicher verwenden. Das Feld vsz ist also 0. Dadurch werden auch Zombies (danke an Stephane Chazelas für diese Beobachtung) abgefangen , die basierend auf ihrem Status eliminiert werden können.

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

So listen Sie nur die PIDs auf:

ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
Gilles 'SO - hör auf böse zu sein'
quelle
Wie meine Lösung wird es auch Zombie-Prozesse enthalten.
Stéphane Chazelas
1
@StephaneChazelas Guter Punkt, ich habe dem Filter eine Bedingung hinzugefügt.
Gilles 'SO - hör auf, böse zu sein'
9

In der Praxis habe ich folgende Redewendung gefunden:

ps auxf | grep -v ]$

Es filtert Zeilen, die mit eckigen Klammern enden, was dazu führen kann, dass unerwünschte Eingaben ausgelassen werden, aber es ist sehr unwahrscheinlich. Im Gegenzug ist es leicht zu merken und relativ schnell zu tippen.

Einige Prozesse wie avahi-daemon ergänzen ihre Prozessnameninformationen in Klammern (der Hostname im Fall von avahi-daemon) und werden von diesem Befehl herausgefiltert.

onetom
quelle
8

Eine Besonderheit dieser Prozesse ist, dass sie nicht durch eine ausführbare Datei gesichert werden. Sie können also Folgendes tun ( in zsh ):

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

Oder mit jeder POSIX-Shell:

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

Das heißt, es wird nach Prozessen gesucht, bei denen /proc/<pid>/exees sich um einen Link zu einer Datei handelt.

Das bedeutet aber, dass Sie Superuser sein müssen, um den Status des /proc/<pid>/exeSymlinks überprüfen zu können .

Bearbeiten : In diesem Fall erfüllen die Zombie-Prozesse (zumindest) dieselbe Bedingung. Wenn Sie also nicht möchten, dass sie ausgeschlossen werden, müssen Sie sie erneut hinzufügen. Mögen:

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

Beachten Sie, dass ps -fdiese Prozessnamen in eckigen Klammern angezeigt werden, nicht weil es sich um Kernelprozesse handelt, sondern weil sie leer sind argv[](daher zeigt ps den Prozessnamen statt argv[0]dort an). Sie können einen User-Space-Prozess auch mit einem leeren argv[]und einen Prozessnamen mit einem argv[0]Formular haben, [some-string]sodass das Filtern der psAusgabe anhand dieser eckigen Klammern keine narrensichere Option ist.

Stéphane Chazelas
quelle
Ich denke, dies ist keine Standard-Shell-Syntax.
Totor
1
@Totor, wie gesagt, die erste ist die zshSyntax. Die zweite ist die Standard-POSIX- Syntax sh( psund findund cutund paste). Natürlich /procwird von POSIX nicht spezifiziert.
Stéphane Chazelas
Akzeptiere diese Antwort, weil sie universell ist (danke für die Bearbeitung). Die Antwort von Hauke ​​Laging ist aber auch ganz nett und unkompliziert, solange Sie sich nicht mit einem 2.4er Kernel beschäftigen.
Totor
@Totor, Haukes Antwort hat auch den Vorteil, dass kein Superuser-Privileg erforderlich ist. Meine Antwort funktioniert mit 2.4- und 2.6 / 3-Kerneln, aber ich nehme an, es gibt keine Garantie, dass es in 4.x trotzdem funktioniert.
Stéphane Chazelas
Hmm, Sie haben Recht, ich habe nicht über Root-Rechte nachgedacht. Es kann zu Fehlern führen, da Sie immer noch eine Antwort erhalten, wenn Sie nicht root sind, aber es ist anders (also müssen Sie vorsichtig sein, wenn Sie sie zählen, sagen wir wc -l). Dann nehme ich die Antwort von Hauke ​​Laging an und stimme Ihnen zu. ;)
Totor
1

Sie können auch einfach die psAusgabe analysieren und nach Prozessnamen suchen, die nicht in Klammern stehen:

ps aux | awk '$NF!~/^\[.+\]$/'
terdon
quelle
Eine etwas weniger zuverlässige Methode, um die Liste der Benutzer abzurufen, an denen Sie interessiert sind: awk -F: '$7 ~ home { print $1 }' /etc/passwd- Es werden jedoch weiterhin Prozesse angezeigt, die einen solchen Benutzernamen erwähnen , und Sie lassen die temporäre Datei herumliegen. Ich werde meine Ablehnung zurückziehen, aber nur, weil Ihre dritte Lösung vernünftig ist.
Keith Thompson
Bah, du hast den ganzen Weg Recht, @KeithThompson, entfernte die anderen, sie sind es nicht wert. Könnten Sie mir helfen, die (jetzt) ​​veralteten Kommentare zu bereinigen?
Terdon
2
Beachten Sie, dass dies $NFdas letzte Wort der Befehlszeile in der ps auxAusgabe ist. Nicht-Kernel-Prozesse können dort haben [...]. Wie ich in meiner Antwort sagte, handelt es sich bei der [xxx]Notation nicht um Kernelprozesse, sondern um eine Befehlszeile (kein Argument), die auch für Nicht-Kernelprozesse zulässig ist.
Stéphane Chazelas
1

Für alle, die dies in einer psstark vereinfachten und anders ausgegebenen Busybox versuchen , ist diese Variante der großartigen Antwort von Gilles eine gute Wahl :

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

Laut Gilles 'Antwort besteht die Methode darin, Prozesse zu finden, die keinen Benutzerspeicher verwenden (`vsz col == 0) und Zombie-Prozesse herauszufiltern (Status col ist nicht' Z ').

Ausgabespalten können einfach angepasst werden, solange die 1-basierten awk-Feldnummern entsprechend angepasst werden. Zeigen Sie die verfügbaren Optionen Ihres ps an, indem Sie einen falschen Wert eingeben. Zum Beispiel:

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

Wenn Sie nur die Anzahl benötigen ... Ich hatte ein ähnliches Bedürfnis, Kernel- und Benutzerprozesse zu filtern, aber ich brauchte jeweils nur die jeweilige Anzahl. Das war meine Lösung:

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]}'

Beispielausgabe :

Kernel processes    353
User processes       52
Total processes     405

Erläuterung : Ich verwende den Hack, bei dem angenommen wird, dass VSZ = 0-Prozesse Kernelprozesse sind. Also mit awk, ich bewerte einen Vergleich über VSZ (von ps -eo vsize), ob es gleich Null ist. Das Ergebnis des Vergleichs ist entweder eine boolesche 0 oder 1. Ich erstelle ein Array p[], und wenn ich die Liste der Prozesse durchlaufe, inkrementiere ich, wenn es sich um einen Kernelprozess handelt p[1]++. Ansonsten inkrementiere ich als Benutzerprozess p[0]++. Nach all dem Inkrementieren beschrifte und drucke ich die Werte (dh Zählwerte) für p [0] und p [1] im END { }Block.

Joshua Huber
quelle
0

Was Sie suchen, mein Freund, ist nicht ps, aber pstree.

Ermitteln Sie zunächst den ersten Kernelprozess. Seine PID ist normalerweise 1 im System ohne systemd und 2 im Systemd.

Dann benutze diesen Befehl:

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

Die ausgewählte Antwort (eine mit ✅) verwendet einen anderen Befehl:

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

Das Problem bei diesem psBefehl ist, dass nur direkte untergeordnete Elemente, aber nicht alle untergeordneten Elemente enthalten sind. Der pstreeBefehl enthält alle Nachkommen. Sie können die Ausgabe dieser beiden Befehle vergleichen und zählen (eine einfache Möglichkeit ist die Verwendung | wc), um sie zu überprüfen.

ssppjj
quelle