ps สามารถแสดงกระบวนการที่ไม่ใช่เคอร์เนลบน Linux ได้หรือไม่


คำตอบ:


37

สิ่งนี้ควรทำ (ภายใต้ Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) มี PPID 0 ( บน Linux 2.6+ ) แต่psไม่อนุญาตให้กรอง PPID 0 ดังนั้นการแก้ไขนี้


ดีมาก แต่รับประกันได้อย่างไรว่าkthreaddเป็น PID 2 เสมอ
l0b0

@ l0b0 ฉันไม่มีความคิด :-) คุณสามารถทำได้สองขั้นตอน: กำหนด PID จากkthreaddนั้นสร้างการpsโทรตาม รับประกันได้อย่างไรว่าสิ่งนี้จะ "ถูกเรียกว่า" เสมอ "kthreadd"? วิธีแก้ปัญหาที่ปลอดภัยจะซับซ้อนมากขึ้นเรียกใช้psตามปกติและแยกวิเคราะห์ผลลัพธ์อาจทำการทดสอบบางอย่าง
Hauke ​​Laging

2
ใน Linux 2.4 บน x86 arch อย่างน้อยกระบวนการเหล่านั้นมี ppid 1 ดังนั้นจึงไม่สามารถแยกแยะได้
Stéphane Chazelas

1
เป็นเหมือน "ps -ef" ทำ "ps - ppp 2 -p 2 - เลือก -f" และทำเช่น "ps aux" ทำ "ps --ppid 2 -p 2 - เลือก u"
Peter

1
@Totor ฉันตรวจสอบแล้วและดูเหมือนว่าเป็นxธงที่ไม่สามารถใช้งานได้ ps au --ppid 2 -p 2 --deselectทำงานได้ดี
Sankalp

9

วิธีหนึ่งในการรับรู้กระบวนการเคอร์เนลคือพวกเขาไม่ได้ใช้หน่วยความจำของผู้ใช้ดังนั้นฟิลด์ vsz คือ 0 นี่ยังจับซอมบี้ (ด้วยStephane Chazelasสำหรับการสังเกตนี้) ซึ่งสามารถกำจัดได้ตามสถานะของพวกเขา

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

ในการแสดงรายการ PID เพียงอย่างเดียว:

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

เช่นเดียวกับโซลูชันของฉันก็จะรวมถึงกระบวนการซอมบี้
Stéphane Chazelas

1
@StephaneChazelas จุดที่ดีฉันได้เพิ่มเงื่อนไขในตัวกรอง
Gilles 'SO- หยุดความชั่วร้าย'

9

ในทางปฏิบัติฉันพบสำนวนดังต่อไปนี้มากพอ:

ps auxf | grep -v ]$

มันกรองบรรทัดที่ลงท้ายด้วยเครื่องหมายวงเล็บซึ่งอาจส่งผลให้ละเว้นรายการที่ไม่ต้องการ แต่มันไม่น่าเป็นไปได้มาก ในการแลกเปลี่ยนมันค่อนข้างง่ายต่อการจดจำและค่อนข้างรวดเร็วในการพิมพ์

กระบวนการบางอย่างเช่น avahi-daemon เพิ่มข้อมูลชื่อกระบวนการของพวกเขาในวงเล็บ (ชื่อโฮสต์ในกรณีของ avahi-daemon) และจะถูกกรองออกโดยคำสั่งนี้


8

หนึ่งในความพิเศษของกระบวนการเหล่านั้นก็คือพวกเขาไม่ได้รับการสนับสนุนจากไฟล์ปฏิบัติการดังนั้นคุณสามารถทำได้ ( ใน zsh ):

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

หรือกับ POSIX เชลล์:

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

นั่นคือตรวจสอบกระบวนการที่/proc/<pid>/exeมีลิงก์ไปยังไฟล์

แต่นั่นหมายความว่าคุณต้องเป็น superuser เพื่อให้สามารถตรวจสอบสถานะของ/proc/<pid>/exesymlink ได้

แก้ไข : มันเกิดขึ้นกับกระบวนการซอมบี้ (อย่างน้อย) เป็นไปตามเงื่อนไขเดียวกันดังนั้นหากคุณไม่ต้องการให้แยกออกคุณจะต้องเพิ่มกลับเข้าไปใหม่ ชอบ:

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

โปรดทราบว่าps -fจะแสดงชื่อกระบวนการเหล่านั้นในวงเล็บเหลี่ยมไม่ใช่เพราะมันเป็นกระบวนการเคอร์เนล แต่เพราะมันว่างเปล่าargv[](ดังนั้น ps แสดงชื่อกระบวนการแทนที่จะargv[0]มี) คุณสามารถมีกระบวนการพื้นที่ผู้ใช้ที่ว่างเปล่าargv[]เช่นกันและคุณสามารถมีชื่อกระบวนการที่มีargv[0]รูปแบบ[some-string]ดังนั้นการกรองpsผลลัพธ์ตามวงเล็บเหลี่ยมเหล่านั้นไม่ใช่ตัวเลือกที่เข้าใจผิดได้


นี่คือไวยากรณ์ของเชลล์ที่ไม่ได้มาตรฐานฉันคิดว่า
Totor

1
@Totor อย่างที่ฉันบอกไว้สิ่งแรกคือzshไวยากรณ์ ที่สองคือ POSIX มาตรฐานsh(และpsและfindและcutและpaste) ไวยากรณ์ แน่นอน/procว่าไม่ได้ระบุโดย POSIX
Stéphane Chazelas

ยอมรับคำตอบนี้เพราะเป็นสากล (ขอบคุณสำหรับการแก้ไข) อย่างไรก็ตามคำตอบของHauke ​​Lagingก็ค่อนข้างดีและตรงไปตรงมาตราบใดที่คุณไม่ได้จัดการกับเคอร์เนล 2.4
Totor

@Totor คำตอบของ Hauke ​​ยังมีข้อได้เปรียบที่ไม่ต้องใช้สิทธิ์ superuser คำตอบของฉันทำงานได้กับเมล็ด 2.4 และ 2.6 / 3 แต่ฉันคิดว่ามันไม่ได้รับประกันว่ามันจะทำงานใน 4.x ต่อไป
Stéphane Chazelas

อืมคุณพูดถูกฉันไม่ได้คิดถึงสิทธิ์ของรูท อาจนำไปสู่ข้อผิดพลาดเนื่องจากคุณยังได้รับคำตอบเมื่อคุณไม่ได้รูท แต่มันแตกต่างกัน (ดังนั้นคุณจะต้องระมัดระวังเมื่อนับพวกเขาด้วยพูดwc -l) ฉันจะยอมรับคำตอบของHauke ​​Lagingแล้วให้รางวัลกับคุณ ;)
Totor

1

คุณสามารถแยกวิเคราะห์psผลลัพธ์และค้นหาชื่อกระบวนการที่ไม่อยู่ในวงเล็บ:

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

วิธีที่ไม่น่าเชื่อถือน้อยกว่าเล็กน้อยในการรับรายชื่อผู้ใช้ที่คุณสนใจ: awk -F: '$7 ~ home { print $1 }' /etc/passwd- แต่คุณจะยังคงได้รับกระบวนการที่พูดถึงชื่อผู้ใช้ดังกล่าวและคุณจะปล่อยให้ไฟล์ชั่วคราววางอยู่รอบ ๆ ฉันจะถอน downvote ของฉัน แต่เพียงเพราะโซลูชันที่สามของคุณมีเหตุผล
Keith Thompson

Bah คุณพูดถูกแล้ว @KeithThompson เอาคนอื่นออกพวกเขาไม่คุ้มค่า คุณช่วยฉันล้างความคิดเห็นที่ล้าสมัยไปแล้วได้ไหม?
terdon

2
โปรดทราบว่า$NFเป็นคำสุดท้ายของบรรทัดคำสั่งในการps auxส่งออก กระบวนการที่ไม่ใช่เคอร์เนลสามารถมี[...]มี ดังที่ฉันพูดในคำตอบของฉัน[xxx]สัญกรณ์ไม่ใช่เพราะเป็นกระบวนการเคอร์เนล แต่เนื่องจากไม่มีบรรทัดคำสั่ง (ไม่มีอาร์กิวเมนต์) ซึ่งได้รับอนุญาตด้วยกระบวนการที่ไม่ใช่เคอร์เนล
Stéphane Chazelas

1

สำหรับทุกคนที่ลองใช้งานนี้ใน busybox ซึ่งpsมีการลดความซับซ้อนอย่างมากและเอาต์พุตแตกต่างกันคำตอบที่ยอดเยี่ยมของ Gilles นี้ใช้ได้ดี:

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

ตามคำตอบของ Gilles วิธีการที่นี่คือการค้นหากระบวนการที่ไม่ได้ใช้หน่วยความจำผู้ใช้ (`vsz col == 0) และกรองกระบวนการซอมบี้ (สถานะ col ไม่ใช่ 'Z')

คอลัมน์เอาต์พุตสามารถปรับได้อย่างง่ายดายตราบใดที่มีการปรับหมายเลขฟิลด์ awk 1 รายการ ดูตัวเลือก ps ของคุณที่มีอยู่โดยใส่ค่าปลอมและมันจะบอกคุณ ตัวอย่างเช่น:

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

0

หากคุณต้องการเพียงการนับ ... ฉันมีความต้องการคล้ายกันในการกรองเคอร์เนลเทียบกับกระบวนการของผู้ใช้ แต่ฉันต้องการเพียงการนับตามลำดับของแต่ละรายการ นี่คือทางออกของฉัน:

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

ตัวอย่างผลลัพธ์ :

Kernel processes    353
User processes       52
Total processes     405

คำอธิบาย : ฉันใช้แฮ็คที่กระบวนการ VSZ = 0 สามารถสันนิษฐานได้ว่าเป็นกระบวนการเคอร์เนล ดังนั้นด้วยawkฉันประเมินการเปรียบเทียบ VSZ (จากps -eo vsize) ไม่ว่าจะเท่ากับศูนย์ ผลของการเปรียบเทียบจะเป็นได้ทั้งแบบบูล 0 หรือ 1 ผมทำอาร์เรย์และเป็นฉันวิ่งลงรายชื่อของกระบวนการถ้ามันเป็นกระบวนการเคอร์เนลผมเพิ่มขึ้นp[] มิฉะนั้นเป็นกระบวนการใช้ผมเพิ่มขึ้นp[1]++ p[0]++หลังจากการเพิ่มขึ้นทั้งหมดฉันติดป้ายกำกับและพิมพ์ค่า (เช่นจำนวน) สำหรับ p [0] และ p [1] ในEND { }บล็อก


0

สิ่งที่คุณกำลังมองหาเพื่อนของฉันไม่ได้แต่pspstree

ก่อนอื่นให้ระบุกระบวนการเคอร์เนลแรก PID ของมันเป็นปกติ 1 ในระบบที่ไม่มี systemd และ 2 กับ systemd

จากนั้นใช้คำสั่งนี้:

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

คำตอบที่เลือก (ข้อที่มี✅) กำลังใช้คำสั่งอื่น:

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

ปัญหาเกี่ยวกับpsคำสั่งนี้คือมันมีเฉพาะลูกโดยตรง แต่ไม่ใช่ลูกหลานทั้งหมด pstreeคำสั่งรวมถึงลูกหลาน คุณสามารถเปรียบเทียบและนับผลลัพธ์ของคำสั่งทั้งสองนี้ (วิธีใช้อย่างง่าย| wc) เพื่อตรวจสอบ

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.