ฉันpsจะขอให้แสดงเฉพาะกระบวนการของผู้ใช้และไม่ใช่เคอร์เนลเธรดได้อย่างไร
ดูคำถามนี้เพื่อดูว่าฉันหมายถึงอะไร ...
ฉันpsจะขอให้แสดงเฉพาะกระบวนการของผู้ใช้และไม่ใช่เคอร์เนลเธรดได้อย่างไร
ดูคำถามนี้เพื่อดูว่าฉันหมายถึงอะไร ...
คำตอบ:
สิ่งนี้ควรทำ (ภายใต้ Linux):
ps --ppid 2 -p 2 --deselect
kthreadd(PID 2) มี PPID 0 ( บน Linux 2.6+ ) แต่psไม่อนุญาตให้กรอง PPID 0 ดังนั้นการแก้ไขนี้
kthreaddนั้นสร้างการpsโทรตาม รับประกันได้อย่างไรว่าสิ่งนี้จะ "ถูกเรียกว่า" เสมอ "kthreadd"? วิธีแก้ปัญหาที่ปลอดภัยจะซับซ้อนมากขึ้นเรียกใช้psตามปกติและแยกวิเคราะห์ผลลัพธ์อาจทำการทดสอบบางอย่าง
xธงที่ไม่สามารถใช้งานได้ ps au --ppid 2 -p 2 --deselectทำงานได้ดี
วิธีหนึ่งในการรับรู้กระบวนการเคอร์เนลคือพวกเขาไม่ได้ใช้หน่วยความจำของผู้ใช้ดังนั้นฟิลด์ 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}'
ในทางปฏิบัติฉันพบสำนวนดังต่อไปนี้มากพอ:
ps auxf | grep -v ]$
มันกรองบรรทัดที่ลงท้ายด้วยเครื่องหมายวงเล็บซึ่งอาจส่งผลให้ละเว้นรายการที่ไม่ต้องการ แต่มันไม่น่าเป็นไปได้มาก ในการแลกเปลี่ยนมันค่อนข้างง่ายต่อการจดจำและค่อนข้างรวดเร็วในการพิมพ์
กระบวนการบางอย่างเช่น avahi-daemon เพิ่มข้อมูลชื่อกระบวนการของพวกเขาในวงเล็บ (ชื่อโฮสต์ในกรณีของ avahi-daemon) และจะถูกกรองออกโดยคำสั่งนี้
หนึ่งในความพิเศษของกระบวนการเหล่านั้นก็คือพวกเขาไม่ได้รับการสนับสนุนจากไฟล์ปฏิบัติการดังนั้นคุณสามารถทำได้ ( ใน 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ผลลัพธ์ตามวงเล็บเหลี่ยมเหล่านั้นไม่ใช่ตัวเลือกที่เข้าใจผิดได้
zshไวยากรณ์ ที่สองคือ POSIX มาตรฐานsh(และpsและfindและcutและpaste) ไวยากรณ์ แน่นอน/procว่าไม่ได้ระบุโดย POSIX
wc -l) ฉันจะยอมรับคำตอบของHauke Lagingแล้วให้รางวัลกับคุณ ;)
คุณสามารถแยกวิเคราะห์psผลลัพธ์และค้นหาชื่อกระบวนการที่ไม่อยู่ในวงเล็บ:
ps aux | awk '$NF!~/^\[.+\]$/'
awk -F: '$7 ~ home { print $1 }' /etc/passwd- แต่คุณจะยังคงได้รับกระบวนการที่พูดถึงชื่อผู้ใช้ดังกล่าวและคุณจะปล่อยให้ไฟล์ชั่วคราววางอยู่รอบ ๆ ฉันจะถอน downvote ของฉัน แต่เพียงเพราะโซลูชันที่สามของคุณมีเหตุผล
$NFเป็นคำสุดท้ายของบรรทัดคำสั่งในการps auxส่งออก กระบวนการที่ไม่ใช่เคอร์เนลสามารถมี[...]มี ดังที่ฉันพูดในคำตอบของฉัน[xxx]สัญกรณ์ไม่ใช่เพราะเป็นกระบวนการเคอร์เนล แต่เนื่องจากไม่มีบรรทัดคำสั่ง (ไม่มีอาร์กิวเมนต์) ซึ่งได้รับอนุญาตด้วยกระบวนการที่ไม่ใช่เคอร์เนล
สำหรับทุกคนที่ลองใช้งานนี้ใน 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
หากคุณต้องการเพียงการนับ ... ฉันมีความต้องการคล้ายกันในการกรองเคอร์เนลเทียบกับกระบวนการของผู้ใช้ แต่ฉันต้องการเพียงการนับตามลำดับของแต่ละรายการ นี่คือทางออกของฉัน:
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 { }บล็อก
สิ่งที่คุณกำลังมองหาเพื่อนของฉันไม่ได้แต่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) เพื่อตรวจสอบ
kthreaddเป็น PID 2 เสมอ