Wie kann ich ps
nur Benutzerprozesse und keine Kernel-Threads anzeigen lassen?
Sehen Sie diese Frage, um zu sehen, was ich meine ...
Wie kann ich ps
nur Benutzerprozesse und keine Kernel-Threads anzeigen lassen?
Sehen Sie diese Frage, um zu sehen, was ich meine ...
Antworten:
Dies sollte (unter Linux) tun:
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) hat PPID 0 ( unter Linux 2.6+ ), ps
erlaubt jedoch kein Filtern nach PPID 0; also diese umgehung.
kthreadd
, dann baue den entsprechenden ps
Aufruf auf. Wie sicher ist es, dass dieses Ding "immer" "kthreadd" heißt? Eine sichere Lösung wäre komplizierter, würde ps
normal ablaufen und die Ausgabe analysieren, möglicherweise einige Tests durchführen.
x
Flagge ist, die damit nicht funktioniert. ps au --ppid 2 -p 2 --deselect
funktioniert ok
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}'
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.
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>/exe
es sich um einen Link zu einer Datei handelt.
Das bedeutet aber, dass Sie Superuser sein müssen, um den Status des /proc/<pid>/exe
Symlinks ü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 -f
diese 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 ps
Ausgabe anhand dieser eckigen Klammern keine narrensichere Option ist.
zsh
Syntax. Die zweite ist die Standard-POSIX- Syntax sh
( ps
und find
und cut
und paste
). Natürlich /proc
wird von POSIX nicht spezifiziert.
wc -l
). Dann nehme ich die Antwort von Hauke Laging an und stimme Ihnen zu. ;)
Sie können auch einfach die ps
Ausgabe analysieren und nach Prozessnamen suchen, die nicht in Klammern stehen:
ps aux | awk '$NF!~/^\[.+\]$/'
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.
$NF
das letzte Wort der Befehlszeile in der ps aux
Ausgabe 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.
Für alle, die dies in einer ps
stark 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
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.
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 ps
Befehl ist, dass nur direkte untergeordnete Elemente, aber nicht alle untergeordneten Elemente enthalten sind. Der pstree
Befehl 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.
kthreadd
immer PID 2 ist?