Bisakah ps menampilkan hanya proses non kernel di Linux?

Jawaban:

37

Ini harus dilakukan (di Linux):

ps --ppid 2 -p 2 --deselect

kthreadd(PID 2) memiliki PPID 0 ( di Linux 2.6+ ) tetapi pstidak mengizinkan filter untuk PPID 0; jadi ini bekerja-sekitar.

Hauke ​​Laging
sumber
Bagus, tapi bagaimana dijamin itu kthreaddselalu PID 2?
l0b0
@ l0b0 Saya tidak tahu :-) Anda bisa melakukan ini dalam dua langkah: Tentukan PID kthreadd, lalu buat pspanggilan yang sesuai . Seberapa terjaminkah hal ini akan "selalu" disebut "kthreadd"? Solusi yang aman akan lebih rumit, berjalan psnormal dan parsing output, lakukan beberapa tes mungkin.
Hauke ​​Laging,
2
Di Linux 2.4 pada arch x86 setidaknya, proses-proses tersebut memiliki ppid 1 sehingga tidak bisa dibedakan seperti itu.
Stéphane Chazelas
1
menjadi seperti "ps -ef" do "ps --ppid 2 -p 2 --pilih -f" dan melakukannya seperti "ps aux" do "ps --ppid 2 -p 2 --memilih u"
Peter
1
@ Motor saya memeriksa dan sepertinya itu adalah xbendera yang tidak berfungsi dengan ini. ps au --ppid 2 -p 2 --deselectbekerja dengan baik.
Sankalp
9

Salah satu cara untuk mengenali proses kernel adalah mereka tidak menggunakan memori pengguna, jadi bidang vsz adalah 0. Ini juga menangkap zombie (terima kasih kepada Stephane Chazelas untuk pengamatan ini), yang dapat dihilangkan berdasarkan statusnya.

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

Untuk hanya daftar PID:

ps -e -o pid= -o state= -o vsize= | awk '$2 != "Z" && $3 != 0 {print $1}'
Gilles 'SANGAT berhenti menjadi jahat'
sumber
Seperti solusi saya, itu juga akan mencakup proses zombie.
Stéphane Chazelas
1
@StephaneChazelas Poin bagus, saya telah menambahkan kondisi ke filter.
Gilles 'SO- berhenti bersikap jahat'
9

Dalam praktik saya menemukan idiom berikut cukup:

ps auxf | grep -v ]$

Memfilter baris yang diakhiri dengan tanda kurung, yang mungkin mengakibatkan menghilangkan entri yang tidak diinginkan tetapi sangat tidak mungkin. Sebagai gantinya, cukup mudah diingat dan relatif cepat untuk mengetik.

Beberapa proses seperti avahi-daemon menambah informasi nama proses mereka dalam tanda kurung (nama host dalam kasus avahi-daemon) dan akan disaring oleh perintah ini.

onetom
sumber
8

Salah satu kekhasan dari proses-proses tersebut adalah bahwa mereka tidak didukung oleh file yang dapat dieksekusi, sehingga Anda dapat melakukannya ( dalam zsh ):

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

Atau dengan shell POSIX:

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

Itu adalah memeriksa proses yang /proc/<pid>/exemerupakan tautan ke file.

Tetapi itu berarti Anda harus menjadi pengguna super untuk dapat memeriksa keadaan /proc/<pid>/exesymlink.

Sunting : Ketika terjadi proses zombie (setidaknya) memenuhi kondisi yang sama, jadi jika Anda tidak ingin mereka dikecualikan, Anda harus menambahkannya kembali. Seperti:

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

Catatan yang ps -fmenunjukkan nama-nama proses dalam tanda kurung siku bukan karena mereka adalah proses kernel, tetapi karena mereka memiliki kosong argv[](jadi ps menunjukkan nama proses bukan di argv[0]sana). Anda dapat memiliki proses ruang pengguna dengan yang kosong argv[]juga dan Anda dapat memiliki nama proses dengan argv[0]yang dari bentuk [some-string]sehingga menyaring psoutput berdasarkan kurung persegi itu bukan pilihan yang mudah.

Stéphane Chazelas
sumber
Ini bukan sintaks shell standar, saya rasa.
Totor
1
@ Motor, seperti yang saya katakan, yang pertama adalah zshsintaks. Yang kedua adalah sintaks POSIX standar sh(dan psdan finddan cutdan paste). Tentu saja /proctidak ditentukan oleh POSIX.
Stéphane Chazelas
Menerima jawaban ini karena bersifat universal (terima kasih atas hasil editnya). Namun, jawaban Hauke ​​Laging juga cukup bagus dan mudah selama Anda tidak berurusan dengan kernel 2.4.
Totor
@ Motor, jawaban Hauke ​​juga memiliki keuntungan karena tidak memerlukan hak superuser. Jawaban saya bekerja dengan kernel 2.4 dan 2.6 / 3, tapi saya kira tidak ada jaminan itu akan bekerja di 4.x.
Stéphane Chazelas
Hmm, Anda benar, saya tidak memikirkan hak root. Ini dapat menyebabkan kesalahan karena Anda masih mendapatkan jawaban ketika Anda tidak melakukan root, tetapi itu berbeda (jadi Anda harus berhati-hati ketika menghitungnya dengan, katakanlah wc -l). Baiklah, saya akan menerima jawaban Hauke ​​Laging , dan memberi Anda jawaban. ;)
Totor
1

Anda juga bisa mem-parsing psoutput dan mencari nama proses yang tidak dalam tanda kurung:

ps aux | awk '$NF!~/^\[.+\]$/'
terdon
sumber
Cara yang sedikit kurang dapat diandalkan untuk mendapatkan daftar pengguna yang Anda minati: awk -F: '$7 ~ home { print $1 }' /etc/passwd- tetapi Anda masih akan mendapatkan proses yang menyebutkan nama pengguna tersebut, dan Anda akan membiarkan file temp tetap berada di sana. Saya akan menarik downvote saya, tetapi hanya karena solusi ketiga Anda masuk akal.
Keith Thompson
Bah, kau benar sekali, @KeithThompson, menghapus yang lain, mereka tidak layak. Bisakah Anda membantu saya membersihkan komentar usang (sekarang)?
terdon
2
Perhatikan bahwa $NFini adalah kata terakhir dari baris perintah dalam ps auxoutput. Proses non-kernel bisa [...]ada di sana. Seperti yang saya katakan di jawaban saya [xxx]notasi bukan karena mereka adalah proses kernel, tetapi karena mereka tidak memiliki baris perintah (tidak ada argumen) yang juga diperbolehkan untuk proses non-kernel.
Stéphane Chazelas
1

Bagi siapa pun yang mencoba ini di busybox psyang sangat disederhanakan dan hasilnya berbeda, varian jawaban hebat Gilles ini berfungsi dengan baik:

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

Sesuai jawaban Gilles, metodologi di sini adalah menemukan proses yang tidak menggunakan memori pengguna mana pun (`vsz col == 0), dan memfilter proses zombie (status col bukan 'Z').

Kolom output dapat disesuaikan dengan mudah, selama nomor bidang awk 1 berbasis disesuaikan. Lihat opsi yang tersedia ps Anda dengan memasukkan nilai palsu dan itu akan memberi tahu Anda. Sebagai contoh:

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

Jika Anda hanya perlu menghitung ... Saya memiliki kebutuhan yang sama untuk memfilter proses kernel vs pengguna, tetapi saya hanya perlu menghitung masing-masing. Ini solusi saya:

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

Output sampel :

Kernel processes    353
User processes       52
Total processes     405

Penjelasan : Saya menggunakan retas yang VSZ = 0 proses dapat dianggap sebagai proses kernel. Jadi dengan awk, saya mengevaluasi perbandingan pada VSZ (dari ps -eo vsize), apakah itu sama dengan nol. Hasil perbandingan akan berupa boolean 0 atau 1. Saya membuat array p[], dan ketika saya menjalankan daftar proses, jika itu adalah proses kernel, saya bertambah p[1]++. Kalau tidak, sebagai proses pengguna, saya naik p[0]++. Setelah semua penambahan, saya memberi label dan mencetak nilai (yaitu jumlah) untuk p [0] dan p [1] di END { }blok.

Joshua Huber
sumber
0

Apa yang kamu cari, temanku, bukan ps, tapi pstree.

Pertama, identifikasi proses kernel pertama. PID-nya umumnya 1 pada sistem tanpa systemd dan 2 dengan systemd.

Kemudian gunakan perintah ini:

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

Jawaban yang dipilih (satu dengan ✅) menggunakan perintah lain:

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

Masalah dengan psperintah ini adalah bahwa itu hanya mencakup anak-anak langsung tetapi tidak semua keturunan. The pstreeperintah mencakup semua keturunan. Anda dapat membandingkan dan menghitung output dari kedua perintah ini (cara mudah digunakan | wc) untuk memverifikasi.

ssppjj
sumber