Ps có thể chỉ hiển thị các tiến trình không kernel trên Linux không?


Câu trả lời:


37

Điều này nên làm (trong Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) có PPID 0 ( trên Linux 2.6+ ) nhưng pskhông cho phép lọc PPID 0; do đó, công việc này


Đẹp, nhưng làm thế nào đảm bảo nó kthreaddluôn luôn là PID 2?
l0b0

@ l0b0 Tôi không có ý tưởng :-) Bạn có thể thực hiện việc này theo hai bước: Xác định PID của kthreadd, sau đó xây dựng pscuộc gọi theo . Làm thế nào đảm bảo rằng điều này sẽ "luôn luôn" được gọi là "kthreadd"? Một giải pháp an toàn sẽ phức tạp hơn, chạy psbình thường và phân tích đầu ra, có thể thực hiện một số thử nghiệm.
Hauke ​​Laging

2
Trong Linux 2.4 trên vòm x86 ít nhất, các quy trình đó có ppid 1 nên không thể phân biệt được theo cách đó.
Stéphane Chazelas

1
giống như "ps -ef" làm "ps --ppid 2 -p 2 --deselect -f" và làm như "ps aux" do "ps --ppid 2 -p 2 --deselect u"
Peter

1
@Totor Tôi đã kiểm tra và có vẻ như đó là xcờ không hoạt động với cái này. ps au --ppid 2 -p 2 --deselecthoạt động tốt.
Sankalp

9

Một cách để nhận ra các quy trình hạt nhân là họ không sử dụng bất kỳ bộ nhớ người dùng nào, vì vậy trường vsz là 0. Điều này cũng bắt được zombie (nhờ Stephane Chazelas cho quan sát này), có thể được loại bỏ dựa trên trạng thái của họ.

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

Để liệt kê chỉ các PID:

ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'

Giống như giải pháp của tôi, nó cũng sẽ bao gồm các quá trình zombie.
Stéphane Chazelas

1
@StephaneChazelas Điểm hay, tôi đã thêm một điều kiện vào bộ lọc.
Gilles 'SO- đừng trở nên xấu xa'

9

Trong thực tế tôi đã tìm thấy thành ngữ sau đây đủ:

ps auxf | grep -v ]$

Nó lọc các dòng kết thúc bằng dấu ngoặc, có thể dẫn đến bỏ sót các mục không mong muốn nhưng rất khó xảy ra. Đổi lại, nó khá dễ nhớ và gõ tương đối nhanh.

Một số quy trình như avahi-daemon thêm vào thông tin tên quy trình của họ trong ngoặc (tên máy chủ trong trường hợp avahi-daemon) và sẽ được lọc ra bằng lệnh này.


8

Một trong những đặc biệt của các quy trình đó là chúng không được hỗ trợ bởi một tệp thực thi, vì vậy bạn có thể làm ( trong zsh ):

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

Hoặc với bất kỳ vỏ POSIX nào:

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

Đó là kiểm tra các quá trình có /proc/<pid>/exeliên kết đến một tệp.

Nhưng điều đó có nghĩa là bạn cần phải là siêu người dùng để có thể kiểm tra trạng thái của /proc/<pid>/exeliên kết tượng trưng.

Chỉnh sửa : Khi điều đó xảy ra, các quá trình zombie (ít nhất) thỏa mãn điều kiện tương tự, vì vậy nếu bạn không muốn loại trừ chúng, bạn phải thêm lại chúng. Như:

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

Lưu ý rằng ps -fhiển thị các tên quy trình đó trong ngoặc vuông không phải vì chúng là các quy trình hạt nhân, mà vì chúng có một khoảng trống argv[](vì vậy ps hiển thị tên quy trình thay vì argv[0]ở đó). Bạn cũng có thể có một quy trình không gian người dùng với một khoảng trống argv[]và bạn có thể có một tên quy trình với một argv[0]hình thức [some-string]để việc lọc psđầu ra dựa trên các dấu ngoặc vuông đó không phải là một lựa chọn hoàn hảo.


Đây là cú pháp shell không chuẩn, tôi nghĩ.
Totor

1
@Totor, như tôi đã nói, cái đầu tiên là zshcú pháp. Thứ hai là cú pháp POSIX sh( psfindcutpaste) tiêu chuẩn . Tất nhiên /prockhông được chỉ định bởi POSIX.
Stéphane Chazelas

Chấp nhận câu trả lời này vì nó phổ biến (cảm ơn vì đã chỉnh sửa). Tuy nhiên, câu trả lời của Hauke ​​Laging cũng khá hay và đơn giản miễn là bạn không đối phó với kernel 2.4.
Totor

@Totor, câu trả lời của Hauke ​​cũng có lợi thế là không yêu cầu siêu nhân hóa. Câu trả lời của tôi hoạt động với hạt nhân 2.4 và 2.6 / 3, nhưng tôi cho rằng không có gì đảm bảo nó sẽ hoạt động trong 4.x.
Stéphane Chazelas

Hmm, bạn nói đúng, tôi đã không nghĩ về đặc quyền root. Nó có thể dẫn đến sai lầm vì bạn vẫn nhận được câu trả lời khi bạn không root, nhưng nó khác (vì vậy bạn phải thận trọng khi đếm chúng, nói wc -l). Chà, sau đó tôi sẽ chấp nhận câu trả lời của Hauke ​​Laging , và đưa cho bạn một upvote. ;)
Típ

1

Bạn cũng có thể phân tích cú pháp psđầu ra và tìm tên quy trình không có trong ngoặc:

ps aux | awk '$NF!~/^\[.+\]$/'

Một cách ít đáng tin cậy hơn để có được danh sách người dùng mà bạn quan tâm: awk -F: '$7 ~ home { print $1 }' /etc/passwd- nhưng bạn vẫn sẽ nhận được các quy trình đề cập đến bất kỳ tên người dùng nào như vậy và bạn sẽ để lại tệp tạm thời. Tôi sẽ rút downvote của tôi, nhưng chỉ vì giải pháp thứ ba của bạn là hợp lý.
Keith Thompson

Bah, bạn hoàn toàn đúng, @KeithThndry, đã xóa những người khác, họ không xứng đáng. Bạn có thể giúp tôi dọn dẹp những bình luận lỗi thời (bây giờ) không?
terdon

2
Lưu ý rằng đó $NFlà từ cuối cùng của dòng lệnh trong ps auxđầu ra. Các quy trình không hạt nhân có thể có [...]ở đó. Như tôi đã nói trong câu trả lời của mình, [xxx]ký hiệu không phải vì chúng là các tiến trình kernel, mà bởi vì chúng không có dòng lệnh (không có đối số) cũng được phép cho các quá trình không phải kernel.
Stéphane Chazelas

1

Đối với bất kỳ ai đang thử điều này trong busybox, nơi psđược đơn giản hóa nhiều và đầu ra khác nhau, biến thể câu trả lời tuyệt vời này của Gilles hoạt động tốt:

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

Theo câu trả lời của Gilles, phương pháp luận ở đây là tìm các quy trình không sử dụng bất kỳ bộ nhớ người dùng nào (`vsz col == 0) và lọc ra các quy trình zombie (trạng thái col không phải là 'Z').

Các cột đầu ra có thể được điều chỉnh dễ dàng, miễn là số trường awk dựa trên 1 được điều chỉnh tương ứng. Xem các tùy chọn mà ps của bạn có sẵn bằng cách đưa vào một giá trị không có thật và nó sẽ cho bạn biết. Ví dụ:

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

0

Nếu bạn chỉ cần số đếm ... Tôi có nhu cầu tương tự để lọc hạt nhân so với quy trình người dùng, nhưng tôi chỉ cần số lượng tương ứng của từng loại. Đây là giải pháp của tôi:

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

Đầu ra mẫu :

Kernel processes    353
User processes       52
Total processes     405

Giải thích : Tôi đang sử dụng bản hack rằng các quy trình VSZ = 0 có thể được coi là các quy trình kernel. Vì vậy, với awk, tôi đánh giá một so sánh trên VSZ (từ ps -eo vsize), cho dù nó bằng không. Kết quả của phép so sánh sẽ là boolean 0 hoặc 1. Tôi tạo một mảng p[]và khi tôi chạy xuống danh sách các quy trình, nếu đó là một quá trình kernel, tôi sẽ tăng lên p[1]++. Nếu không, như quá trình người dùng, tôi tăng lên p[0]++. Sau khi tăng tất cả, tôi dán nhãn và in các giá trị (nghĩa là đếm) cho p [0] và p [1] trong END { }khối.


0

Những gì bạn đang tìm kiếm, bạn của tôi, không phải ps, nhưng pstree.

Đầu tiên, xác định quá trình kernel đầu tiên. PID của nó thường là 1 trên hệ thống không có systemd và 2 với systemd.

Sau đó sử dụng lệnh này:

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

Câu trả lời được chọn (một với) đang sử dụng lệnh khác:

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

Vấn đề với pslệnh này là nó chỉ bao gồm những đứa trẻ trực tiếp chứ không phải tất cả con cháu. Các pstreelệnh bao gồm tất cả con cháu. Bạn có thể so sánh và đếm đầu ra của hai lệnh này (một cách dễ dàng đang sử dụng | wc) để xác minh.

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.