Temukan (dan bunuh) proses lama

10

Pada dasarnya saya harus dapat memindai pohon proses dan menemukan proses yang cocok dengan nama tertentu dan mulai berjalan lebih dari seminggu. Setelah saya memilikinya, saya harus membunuh mereka. Semua proses masih terlihat dalam keadaan berjalan oleh sistem, hanya saja tidak menggunakan waktu sistem apa pun. Mereka biasanya akan duduk selamanya dalam kondisi ini juga.

Idealnya saya ingin menemukan sesuatu yang mirip, tetapi untuk proses.

Sistem adalah linux Debian dan ini akan dituliskan dan dijalankan oleh cron jadi saya tidak punya masalah nyata dengan sesuatu yang besar tapi bisa dimengerti.

Ryaner
sumber
4
bagaimana Anda akan membedakan antara proses lama tapi penting dan proses yang Anda ingin bunuh?
Chopper3

Jawaban:

9

Anda dapat melakukan ini dengan kombinasi ps, awk dan kill:

ps -eo pid,etime,comm

Memberi Anda output tiga kolom, dengan PID proses, waktu yang berlalu sejak proses dimulai, dan nama perintah, tanpa argumen. Waktu yang berlalu terlihat seperti ini:

mm:ss
hh:mm:ss
d-hh:mm:ss

Karena Anda menginginkan proses yang telah berjalan selama lebih dari seminggu, Anda akan mencari garis yang cocok dengan pola ketiga itu. Anda dapat menggunakan awk untuk memfilter proses dengan menjalankan waktu dan nama perintah, seperti ini:

ps -eo pid,etime,comm | awk '$2~/^7-/ && $3~/mycommand/ { print $1 }'

yang akan mencetak pid dari semua perintah yang cocok dengan 'perintah saya' yang telah berjalan selama lebih dari 7 hari. Pipa daftar itu menjadi kill, dan Anda selesai:

ps -eo pid,etime,comm | awk '$2~/^7-/ && $3~/mycommand/ { print $1 }' | kill -9
Ian Clelland
sumber
Bagus terima kasih. Benar-benar lupa tentang opsi pemformatan di ps.
Ryaner
2
Ini tidak menunjukkan Anda proses menjalankan "lebih dari 7 hari". Ini menunjukkan Anda proses berjalan antara 7 hari tetapi kurang dari 8 hari.
hobodave
etimeslebih berguna - serverfault.com/a/393476/67675
poige
4

killall --quiet --older-than 1w process_name

billyw
sumber
1
Ini berfungsi luar biasa di Ubuntu 16.04 dan Anda dapat menggunakan dengan tanda -i (interaktif) untuk menguji dan memastikannya menargetkan proses yang Anda pikir seharusnya.
ezwrighter
1

Semua info yang Anda butuhkan dapat diambil dari ps -ef. Lihat kolom "STIME". Kombinasikan itu dengan grepuntuk memilah proses yang Anda butuhkan. Pada titik itu, Anda dapat menggunakan cutuntuk mengambil pid dari semua proses yang cocok dan meneruskannya ke kill.

Harap beri tahu saya jika Anda ingin detail lebih lanjut tentang cara melakukan ini.

EEAA
sumber
Saya ingin lebih detail. Jawaban lain sama sekali tidak benar.
hobodave
1

jika Anda root, untuk membuang sampah (/ proc / fs proc / stat ...)

find /proc -maxdepth 1 -regex '/proc/[0-9]*' -type d -mtime +2 -exec basename {} \;

sumber
0

Ketika sebuah proses dimulai, ia menciptakan direktori di sistem file / proc. Anda dapat menggunakan perintah find untuk mendapatkan direktori yang lebih dari 7 hari dan mematikan proses sebagai berikut:

find /proc -user myuser -maxdepth 1 -type d -mtime +7 -exec basename {} \; | xargs kill -9 
dogbane
sumber
Ini juga tidak berhasil. As-is itu menghasilkan peringatan ini, dan tidak ada output tambahan: find: warning: you have specified the -maxdepth option after a non-option argument -user, but options are not positional (-maxdepth affects tests specified before it as well as those specified after it). Please specify options before other arguments.Memindahkan -maxdepth menjadi output pertama tidak menghasilkan proses, dan saya yakin banyak yang harus cocok.
hobodave
juga mengapa mtime tidak ctime jika Anda mencari tanggal pembuatan dir? dir secara teoritis dapat dimodifikasi jika anak tambahan dibuat, yang saya tidak akan mengesampingkan (mungkin modul kernel yang baru dimuat akan memperpanjang sysfs dalam beberapa cara)
jmtd
0

Tidak ada yang menyebutkan ps-watcher di sini. Saya pikir Anda mungkin dapat membandingkan $ start_time menggunakan fungsi elapsed2sec tapi saya tidak sepenuhnya yakin. Inilah pikiran pertama saya:

[myproc]
occurs = every
trigger = elapsed2secs('$start_time') > 7*DAYS
action = <<EOT
  echo "$command has been running more than 7 days" | /bin/mail user\@host
  kill -TERM $pid
EOT

tidak tahu apakah itu berhasil, tetapi itu harus menjadi titik awal yang baik.

Phil Hollenback
sumber