Jak mogę poprosić ps
o wyświetlanie tylko procesów użytkownika, a nie wątków jądra?
Zobacz to pytanie, aby zobaczyć, co mam na myśli ...
Jak mogę poprosić ps
o wyświetlanie tylko procesów użytkownika, a nie wątków jądra?
Zobacz to pytanie, aby zobaczyć, co mam na myśli ...
Odpowiedzi:
Powinno to zrobić (w systemie Linux):
ps --ppid 2 -p 2 --deselect
kthreadd
(PID 2) ma PPID 0 ( w Linuksie 2.6+ ), ale ps
nie pozwala na filtrowanie pod kątem PPID 0; więc to obejście.
kthreadd
, a następnie zbuduj odpowiednie ps
wywołanie. Jak zagwarantowane jest, że to „zawsze” będzie nazywać się „kthreadd”? Bezpieczne rozwiązanie byłoby bardziej skomplikowane, działałoby ps
normalnie i analizowałoby dane wyjściowe, może wykonałby jakieś testy.
x
flaga nie działa z tym. ps au --ppid 2 -p 2 --deselect
działa OK.
Jednym ze sposobów rozpoznania procesów jądra jest to, że nie używają one żadnej pamięci użytkownika, więc pole vsz wynosi 0. To także łapie zombie (dzięki Stephane Chazelas za tę obserwację), które można wyeliminować na podstawie ich statusu.
ps axl | awk '$7 != 0 && $10 !~ "Z"'
Aby wyświetlić tylko PID:
ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
W praktyce znalazłem następujący idiom:
ps auxf | grep -v ]$
Filtruje linie kończące się nawiasami, co może skutkować pominięciem niepożądanych wpisów, ale jest to bardzo mało prawdopodobne. W zamian jest dość łatwy do zapamiętania i stosunkowo szybki do pisania.
Niektóre procesy, takie jak demon avahi, dodają do nawiasów informacje o nazwie procesu (nazwa hosta w przypadku demona avahi) i zostaną odfiltrowane przez to polecenie.
Jedną ze szczególnych cech tych procesów jest to, że nie są one wspierane przez plik wykonywalny, więc możesz zrobić ( w zsh ):
ps /proc/[0-9]*/exe(^-@:h:t)
Lub z dowolną powłoką POSIX:
ps -p "$(find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3 | paste -sd , -)"
To jest sprawdzanie procesów, których /proc/<pid>/exe
link do pliku.
Ale to oznacza, że musisz być superużytkownikiem, aby móc sprawdzić stan /proc/<pid>/exe
dowiązania symbolicznego.
Edycja : Tak się składa, że procesy zombie (przynajmniej) spełniają ten sam warunek, więc jeśli nie chcesz ich wykluczać, musisz je dodać z powrotem. Lubić:
ps -p "$(
{ find -L /proc/[0-9]*/exe ! -type l | cut -d / -f3
ps -Ao pid=,state= | sed -n 's/ Z//p'
} | paste -sd , -)"
Zauważ, że ps -f
pokazuje te nazwy procesów w nawiasach kwadratowych nie dlatego, że są procesami jądra, ale ponieważ mają puste argv[]
(więc ps pokazuje nazwę procesu zamiast argv[0]
tam). Można mieć proces przestrzeni użytkownika z pustym argv[]
jak dobrze i można mieć nazwę procesu z argv[0]
który jest w postaci [some-string]
tak filtrowanie ps
wyjścia opartą na tych nawiasach kwadratowych nie jest opcją niezawodne.
zsh
składnia. Drugi to standardowa składnia POSIX sh
(i ps
oraz find
i cut
i paste
). Oczywiście /proc
nie jest to określone przez POSIX.
wc -l
). Cóż, zaakceptuję odpowiedź Hauke Laging i dam ci głos. ;)
Możesz także po prostu przeanalizować dane ps
wyjściowe i poszukać nazw procesów, które nie są w nawiasach:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd
- ale nadal będziesz otrzymywać procesy, które wspominają taką nazwę użytkownika, i pozostawisz plik tymczasowy leżący w pobliżu. Wycofam moją opinię, ale tylko dlatego, że twoje trzecie rozwiązanie jest rozsądne.
$NF
jest to ostatnie słowo wiersza poleceń w ps aux
danych wyjściowych. Mogą [...]
tam istnieć procesy inne niż jądro . Jak powiedziałem w mojej odpowiedzi [xxx]
notacja nie dlatego, że są procesy jądra, ale ponieważ nie mają linii poleceń (bez argumentów), który jest również dozwolonych procesów non-jądra.
Dla każdego, kto spróbuje tego w busyboksie, gdzie ps
jest bardzo uproszczony, a wyniki są inne, ten wariant świetnej odpowiedzi Gillesa działa dobrze:
ps -o pid,user,comm,vsz,stat | awk '$4 != 0 && $5 !~ "Z"'
Zgodnie z odpowiedzią Gillesa metodologia polega na tym, aby znaleźć procesy, które nie wykorzystują pamięci użytkownika (`vsz col == 0) i odfiltrować procesy zombie (status col nie jest 'Z').
Kolumny wyjściowe można łatwo regulować, o ile odpowiednio zmieniane są liczby pól awk oparte na 1. Zobacz opcje dostępne dla twojego ps, wprowadzając fałszywą wartość, a ci to powie. Na przykład:
$ ps -o foo
ps: bad -o argument 'foo', supported arguments: user,group,comm,args,pid,ppid,pgid,tty,vsz,stat,rss
Jeśli potrzebujesz tylko zliczeń ... Miałem podobną potrzebę filtrowania jądra względem procesów użytkownika, ale potrzebowałem tylko odpowiednich zliczeń każdego z nich. To było moje rozwiązanie:
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]}'
Przykładowe dane wyjściowe :
Kernel processes 353
User processes 52
Total processes 405
Objaśnienie : Używam hacka, że procesy VSZ = 0 można uznać za procesy jądra. Tak więc awk
, oceniam porównanie na VSZ (od ps -eo vsize
), czy jest równe zero. Wynikiem porównania będzie wartość logiczna 0 lub 1. Tworzę tablicę p[]
, a gdy przeglądam listę procesów, jeśli jest to proces jądra, zwiększam p[1]++
. W przeciwnym razie, jako proces użytkownika, zwiększam p[0]++
. Po wszystkich inkrementacjach oznaczam i drukuję wartości (tj. Liczby) dla p [0] i p [1] w END { }
bloku.
Czego szukasz, przyjacielu, nie jest ps
, ale pstree
.
Najpierw zidentyfikuj pierwszy proces jądra. Jego PID to zwykle 1 w systemie bez systemd i 2 z systemd.
Następnie użyj tego polecenia:
$ pstree -p <1 or 2> | grep -o '([0-9]\+)' | grep -o '[0-9]\+'
Wybrana odpowiedź (jedna z ✅) używa innego polecenia:
$ ps --ppid 2 -p 2 --deselect
Problem z tym ps
poleceniem polega na tym, że obejmuje on tylko bezpośrednie dzieci, ale nie wszystkich potomków. pstree
Polecenie zawiera wszystkie elementy podrzędne. Możesz porównać i policzyć dane wyjściowe tych dwóch poleceń (używa się łatwego sposobu | wc
) do weryfikacji.
kthreadd
zawsze jest to PID 2?