Jak znaleźć proces zombie?

100
System information as of Fri Mar  9 19:40:01 KST 2012

  System load:    0.59               Processes:           167
  Usage of /home: 23.0% of 11.00GB   Users logged in:     1
  Swap usage:     0%                 IP address for eth1: 192.168.0.1

  => There is 1 zombie process.

  Graph this data and manage this system at https://landscape.canonical.com/

10 packages can be updated.
4 updates are security updates.

Last login: Fri Mar  9 10:23:48 2012
a@SERVER:~$ ps auxwww | grep 'Z'
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
usera     13572  0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Z
a@SERVER:~$ 

Jak znaleźć ten proces zombie?

Pablo
źródło
dlaczego nie otworzysz monitora systemu i nie poszukasz procesu zombie?
dlin
8
Jak to zrobić na bezgłowym serwerze no-X?
SabreWolfy
2
Zaskakujące, że żadna odpowiedź poniżej nie mówi, że w systemie nie ma procesu zombie opartego na powyższych wynikach. Jeśli tak naprawdę było, ps auxwww | grep 'Z'polecenie powinno pokazywać proces w Zstanie. „Informacja o systemie” => There is 1 zombie process.wydaje się być błędem. Albo to, albo w pytaniu brakuje informacji.
arielf

Odpowiedzi:

126

Aby zabić zombie (proces), musisz zabić jego proces nadrzędny (tak jak prawdziwe zombie!), Ale pytanie brzmiało, jak go znaleźć.

Znajdź zombie (pytanie odpowiedziało na tę część):

a@SERVER:~$ ps aux | grep 'Z'

Dostajesz Zombie i cokolwiek innego z Z, więc dostaniesz także grep:

USER       PID     %CPU %MEM  VSZ    RSS TTY      STAT START   TIME COMMAND
usera      13572   0.0  0.0   7628   992 pts/2    S+   19:40   0:00 grep --color=auto Z
usera      93572   0.0  0.0   0      0   ??       Z    19:40   0:00 something

Znajdź rodzica zombie:

a@SERVER:~$ pstree -p -s 93572

Da tobie:

init(1)---cnid_metad(1311)---cnid_dbd(5145)

W takim przypadku nie chcesz zabijać tego procesu nadrzędnego i powinieneś być całkiem zadowolony z jednego zombie, ale zabicie bezpośredniego procesu nadrzędnego 5145 powinno się go pozbyć.

Dodatkowe zasoby na askubuntu:

Duncanmoo
źródło
1
Rezultatem pokazanym w odpowiedzi jest samo polecenie grep, a nie proces zombie. Jest to ta sama błędna interpretacja, jakiej dokonał Pablo w swojej odpowiedzi. Odpowiedź Rinzwind poniżej faktycznie szuka procesu zombie i wymienia je. Inną opcją może być grep dla „nieistniejącego”
FvD
pstree -H your_desired_pid -p
Greg M. Krsak
Dziękuję Gregowi za dodanie się do dyskusji, ale pamiętaj, że jest to strona pomocy, po prostu wklejenie polecenia bez wyjaśnienia niczego nie jest pomocne dla większości osób przybywających tutaj w poszukiwaniu pomocy.
Duncanmoo,
1
To świetna odpowiedź! Nadal obowiązuje do dziś! Udało mi się znaleźć proces zombie i bez problemu zabić jego proces macierzysty. Dziękuję Ci!
Terrance,
1
jeśli nie masz zainstalowanego pstree, ps wauxfrobi to samo
JDS
35

Mimo że to pytanie jest stare, myślałem, że wszyscy zasługują na bardziej wiarygodną odpowiedź:

ps axo pid=,stat=

To wyemituje dwie kolumny rozdzielone spacjami, z których pierwsza to PID, a druga to jej stan.

Nie sądzę, że nawet GNU pszapewnia sposób na bezpośrednie filtrowanie według stanu, ale można to zrobić niezawodnieawk

ps axo pid=,stat= | awk '$2~/^Z/ { print }'

Masz teraz listę PID, które są zombie. Ponieważ znasz stan, nie jest już konieczne jego wyświetlanie, aby można go było odfiltrować.

ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }'

Podanie rozdzielonej znakami nowej linii identyfikatorów PID zombie.

Możesz teraz operować na tej liście za pomocą prostej pętli powłoki

for pid in $(ps axo pid=,stat= | awk '$2~/^Z/ { print $1 }') ; do
    echo "$pid" # do something interesting here
done

ps jest potężnym narzędziem i nie trzeba robić nic skomplikowanego, aby uzyskać z niego informacje o procesie.

(Znaczenie różnych stanów procesu tutaj - https://unix.stackexchange.com/a/18477/121634 )

Sorpigal
źródło
2
awkjest również potężnym narzędziem, które nie tylko dzieli tekst, ale może go również dopasować. +1 ... inne używane greptam, gdzie jest to niepotrzebne i nieprecyzyjne.
0xC0000022L
więc teraz, kiedy mam listę procesów zombie. jak je zabić?
chovy
@chovy: Będzie to zależeć, ale ogólnie obejmuje zabijanie lub sygnalizowanie rodzica. Inne odpowiedzi tutaj odnoszą się do tego. Z pokazanej powyżej pętli można znaleźć pid rodzicielski w następujący sposób:ps -p "$pid" -opid=,ppid=
Sorpigal,
jeśli to zrobię, czy rodzic nie zabije wszystkich swoich procesów potomnych? Chcę tylko zabić proces jednego zombie. Znam ppid.
chovy
1
Proponuję dodać ppid=do listy opcji, więc nie trzeba używać osobnego polecenia, aby uzyskać ppid.
Ding-Yi Chen
3

ps aux | awk '{ print $8 " " $2 }' | grep -w Z

Od: http://www.cyberciti.biz/tips/killing-zombie-process.html

Z komentarzy ulepszony:

for p in $(ps jauxww | grep Z | grep -v PID | awk '{print $3}'); do
    for every in $(ps auxw | grep $p | grep cron | awk '{print $2}'); do
        kill -9 $every;
    done;
done;

Ostrożnie: ten również zabija proces.

Rinzwind
źródło
wciąż nic nie zwraca. Myślę, że moja droga też nie była zła.
Pablo,
Drugi przykład jest piekielnie niewiarygodny, a pierwszy jest niepotrzebnie gadatliwy (spróbuj ps axo pid=,stat= | awk '$2~/Z/ {print $1}'zamiast tego).
Sorpigal
3

Mniej znaczy więcej:

ps afuwwx | less +u -p'^(\S+\s+){7}Z.*'

To znaczy, daj mi las (drzewo) wszystkich procesów użytkowników w formacie zorientowanym na użytkownika z nieograniczoną szerokością dowolnego tty i pokaż mi go na połowie ekranu powyżej, gdzie pasuje to, że ósma kolumna zawiera Z, i dlaczego nie podświetlić całej linii.

Format zorientowany na użytkownika wydaje się oznaczać: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDwięc status Zombie pojawi się w 8 kolumnie.

Możesz rzucić Nprzed, pjeśli chcesz numery linii, i a, Jjeśli chcesz gwiazdkę na meczu. Niestety, jeśli użyjesz, Gaby nie podświetlać linii, gwiazdka nie będzie pokazywana, choć Jtworzy dla niej miejsce.

W końcu dostajesz coś, co wygląda:

…
  root      2919  0.0  0.0  61432  5852 ?      Ss Jan24 0:00 /usr/sbin/sshd -D
  root     12984  0.0  0.1 154796 15708 ?      Ss 20:20 0:00  \_ sshd: lamblin [priv]
  lamblin  13084  0.0  0.0 154796  9764 ?      S  20:20 0:00      \_ sshd: lamblin@pts/0
* lamblin  13086  0.0  0.0  13080  5056 pts/0  Z  20:20 0:00          \_ -bash <defunct>
  lamblin  13085  0.0  0.0  13080  5056 pts/0  Ss 20:20 0:00          \_ -bash
  root     13159  0.0  0.0 111740  6276 pts/0  S  20:20 0:00              \_ su - nilbmal
  nilbmal  13161  0.2  0.0  13156  5004 pts/0  S  20:20 0:00                  \_ -su
  nilbmal  13271  0.0  0.0  28152  3332 pts/0  R+ 20:20 0:00                      \_ ps afuwwx
  nilbmal  13275  0.0  0.0   8404   848 pts/0  S+ 20:20 0:00                      \_ less +u -Jp^(\S+\s+){7}Z.*
…

Możesz to zrobić za pomocą (i wykryje, czy twój terminal lubi -U Unicode lub -A Ascii):

pstree -psS <PID LIST>

LUB po prostu, wiesz, użyj strzałki w górę, lessaby podążać za tym drzewem / lasem przez hierarchię; to właśnie zalecałem przy podejściu „Mniej znaczy więcej”.

dlamblin
źródło
0

Proponuję ci to polecenie:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'
Peycho Dimitrov
źródło
Używanie auxi mungowanie z niego łańcuchów jest niepotrzebnie niewiarygodne, kiedy możesz użyć -oi zażądać dokładnie tego, czego chcesz. Użyj ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'zamiast tego.
Sorpigal
-1

Aby wyświetlić listę procesowych zombie, wypróbuj to polecenie:

ps j | awk '$7 ~ "Z"'

Może być konieczna zmiana w $7zależności od systemu operacyjnego.

Spowoduje to również zwrócenie listy ich procesów nadrzędnych id ( PPID).

Aby spróbować zabić zombie (po przetestowaniu powyższego polecenia), spróbuj:

kill -9 $(ps j | awk 'NR>1 && $7 ~ "Z" {print $2}')

Aby zidentyfikować swoich rodziców, spróbuj pstree:

$ ps j | awk 'NR>1 && $7 ~ "T" {print $2}' | xargs -L1 pstree -sg
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2430)
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2431)
systemd(1)───sshd(1036)───sshd(2325)───sshd(2325)───bash(2383)───zombie(2432)
kenorb
źródło
Uciekanie się do usuwania jednej kolumny z jformatu jest niepotrzebnie skomplikowane. Użyj -o, aby zamiast tego wybrać, co chcesz.
Sorpigal
2
ps jnie drukuje wszystkich procesów w systemie. Wyświetla tylko informacje o aktualnych procesach użytkownika (w stylu zadań BSD), więc może przegapić procesy zombie.
arielf