Làm thế nào để tìm quá trình 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:~$ 

Làm thế nào để tìm quá trình zombie đó?


Tại sao bạn không mở màn hình hệ thống và tìm kiếm quá trình zombie?
dlin

8
Làm thế nào để làm điều đó trên một máy chủ không đầu X?
SabreWolfy

2
Đáng ngạc nhiên là không có câu trả lời dưới đây thực sự nói rằng không có quá trình zombie trong hệ thống dựa trên đầu ra ở trên. Nếu thực sự có một, ps auxwww | grep 'Z'lệnh sẽ hiển thị một quá trình ở Ztrạng thái. Việc nói "thông tin hệ thống" => There is 1 zombie process.dường như là một lỗi. Hoặc là, hoặc thiếu thông tin trong câu hỏi.
arielf

Câu trả lời:


126

Để tiêu diệt zombie (quy trình), bạn phải giết quy trình cha mẹ của nó (giống như zombie thực sự!), Nhưng câu hỏi là làm thế nào để tìm thấy nó.

Tìm zombie (Câu hỏi đã trả lời phần này):

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

Những gì bạn nhận được là Zombie và bất cứ thứ gì khác có chữ Z trong đó, vì vậy bạn cũng sẽ nhận được 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

Tìm cha mẹ của zombie:

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

Sẽ cung cấp cho bạn:

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

Trong trường hợp này, bạn không muốn giết tiến trình cha mẹ đó và bạn nên khá hài lòng với một zombie, nhưng giết chết tiến trình cha mẹ ngay lập tức 5145 nên loại bỏ nó.

Tài nguyên bổ sung trên Askubfox:


1
Kết quả bạn hiển thị trong câu trả lời của mình là lệnh grep, không phải quá trình zombie. Đó là cách giải thích sai giống như Pablo đưa ra trong câu trả lời của mình. Câu trả lời của Rinzwind dưới đây thực sự tìm kiếm quá trình zombie và liệt kê chúng. Một lựa chọn khác có thể là grep cho "
defposed

pstree -H your_desired_pid -p
Greg M. Krsak

Cảm ơn Greg đã thêm vào cuộc thảo luận, nhưng xin hãy nhớ rằng đây là một trang trợ giúp, chỉ cần dán một lệnh mà không giải thích bất cứ điều gì là không hữu ích cho hầu hết mọi người đến đây để tìm kiếm sự giúp đỡ.
Duncanmoo

1
Đây là một câu trả lời tuyệt vời! Nó vẫn còn hiệu lực ngày hôm nay! Tôi đã có thể tìm thấy quá trình zombie của mình và giết chết quá trình cha mẹ của nó mà không gặp vấn đề gì. Cảm ơn bạn!
Terrance

1
nếu bạn chưa cài đặt pstree, hãy ps wauxflàm điều tương tự
JDS

35

Mặc dù câu hỏi này đã cũ nhưng tôi nghĩ mọi người đều xứng đáng nhận được câu trả lời đáng tin cậy hơn:

ps axo pid=,stat=

Điều này sẽ phát ra hai cột được phân tách bằng khoảng trắng, cột đầu tiên là một cột và cột thứ hai là trạng thái của nó.

Tôi không nghĩ ngay cả GNU pscung cấp một cách để lọc theo trạng thái trực tiếp, nhưng bạn có thể làm điều này một cách đáng tin cậy vớiawk

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

Bây giờ bạn có một danh sách các PID là zombie. Vì bạn biết trạng thái không còn cần thiết để hiển thị trạng thái đó, nên có thể lọc ra.

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

Đưa ra một danh sách các dòng zombie zombie được phân định bằng dòng mới.

Bây giờ bạn có thể hoạt động trong danh sách này với một vòng lặp shell đơn giản

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

ps là một công cụ mạnh mẽ và bạn không cần phải làm bất cứ điều gì phức tạp để có được thông tin xử lý từ nó.

(Ý nghĩa của các trạng thái quá trình khác nhau ở đây - https://unix.stackexchange.com/a/18477/121634 )


2
awkcũng là một công cụ mạnh mẽ không chỉ phân tách văn bản mà còn có thể khớp với nó. +1 ... những cái khác được sử dụng grepkhi không cần thiết và không chính xác.
0xC0000022L

Vì vậy, bây giờ tôi có danh sách các quá trình zombie. Làm thế nào để tôi giết chúng?
chovy

@chovy: Nó sẽ phụ thuộc, nhưng thường liên quan đến việc giết hoặc báo hiệu cho cha mẹ. Các câu trả lời khác ở đây đi vào đó. Từ trong vòng lặp hiển thị ở trên, bạn có thể tìm thấy pid cha như thế này:ps -p "$pid" -opid=,ppid=
Sorpigal

Nếu tôi sẽ cha mẹ sẽ không giết tất cả các quá trình con của nó? Tôi chỉ muốn giết một quá trình zombie. Tôi biết ppid.
chovy

1
Tôi khuyên bạn nên thêm ppid=vào danh sách tùy chọn, vì vậy không cần sử dụng lệnh riêng để lấy ppid.
Đinh-Yi Chen

3

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

Từ: http://www.cyberciti.biz/tips/killing-zombie- Process.html

Từ các ý kiến ​​một cải tiến:

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;

Mặc dù cẩn thận: điều này cũng giết chết các proces.


vẫn không trả lại gì. Tôi nghĩ rằng cách của tôi cũng không sai.
Pablo

Ví dụ thứ 2 là không đáng tin cậy và trước đây là dài dòng không cần thiết ( ps axo pid=,stat= | awk '$2~/Z/ {print $1}'thay vào đó hãy thử ).
Sorpigal

3

Ít hơn là mặc dù:

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

Giống như, hãy cho tôi một rừng (cây) của tất cả các quy trình của người dùng ở định dạng hướng người dùng với chiều rộng không giới hạn trên bất kỳ tty nào và hiển thị cho tôi ở nửa màn hình phía trên nơi khớp với cột thứ 8 chứa Z và Tại sao không làm nổi bật toàn bộ dòng.

Định dạng hướng người dùng dường như có nghĩa là: USER, PID, %CPU, %MEM, VSZ, RSS, TTY, STAT, START, TIME, COMMANDvì vậy trạng thái Zombie sẽ hiển thị trong cột thứ 8.

Bạn có thể ném vào Ntrước pnếu bạn muốn số dòng và Jnếu bạn muốn có dấu hoa thị trong trận đấu. Đáng buồn thay, nếu bạn sử dụng Gđể không làm nổi bật dòng mà dấu hoa thị sẽ không hiển thị, mặc dù Jtạo không gian cho nó.

Bạn cuối cùng nhận được một cái gì đó trông giống như:

…
  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.*
…

Bạn có thể theo dõi điều này với (và nó sẽ phát hiện xem thiết bị đầu cuối của bạn thích -U Unicode hay -A Ascii):

pstree -psS <PID LIST>

HOẶC chỉ, bạn biết, sử dụng mũi tên lên trong lessđể theo cây / rừng đó thông qua hệ thống phân cấp; đó là những gì tôi đã đề xuất với phương pháp "Ít hơn là nhiều hơn".


0

Tôi đề nghị bạn lệnh này:

ps aux | awk '"[Zz]" ~ $8 { printf("%s, PID = %d\n", $8, $2); }'

Việc sử dụng auxvà trộn các chuỗi ra khỏi nó là không đáng tin cậy khi bạn có thể sử dụng -ovà yêu cầu chính xác những gì bạn muốn. Sử dụng ps ax -o pid=,stat= | awk '$2 ~ "[Zz]" { printf("%s, PID = %d\n", $2, $1); }'thay thế.
Sorpigal

-1

Để liệt kê quá trình zombie, hãy thử lệnh này:

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

Bạn có thể cần phải thay đổi $7tùy thuộc vào hệ điều hành của bạn.

Điều này cũng sẽ trả về danh sách id quá trình cha mẹ của họ ( PPID).

Để thử tiêu diệt zombie (sau khi thử lệnh trên), hãy thử:

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

Để xác định cha mẹ của họ, hãy thử với pstree, như:

$ 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)

Sử dụng để tước một cột ra khỏi jđịnh dạng cho việc này là không cần thiết phức tạp. Sử dụng -ođể chọn những gì bạn muốn thay thế.
Sorpigal

2
ps jkhông in tất cả các quy trình trong hệ thống. Nó chỉ liệt kê các procs người dùng hiện tại (theo kiểu công việc BSD) vì vậy nó có thể bỏ lỡ các quy trình zombie.
arielf
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.