Linux bash komut dosyasında belirli bir kullanıcı tarafından 5 dakikadan fazla çalışan tüm işlemleri öldür


18

Belirli bir işlem için en az 5 dakika beri çalışan işlemleri öldürmek için komuta ihtiyacım var.

Bu komutu her beş dakikada bir çalıştırmam gerekecek.

Milyonlarca kez teşekkürler !

(sistem Centos5'tir)

linux  bash 

Yanıtlar:


17
kill -9 $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print $2}}')

burada "procname" bir işlem adıdır ve 300 çalışma zamanı eşiğidir


Harika oneliner. Ben -9süreçlerime biraz dostça olmadan kullandım ve daha grep -v defunct |önce awkgördüğünüz procname <defunct>gibi awk komutunun geçerli bir PID döndürmemesini sağlayacak çıktı olarak ekledim . Ve bu öldürme komutunu bozar.
Michael Härtl

söyleyebilirim $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print "kill "$2}}')biraz daha yumuşak ama cevap yine de harika
Yevgen

@WhiteHat, aynı pid ile bir süreç için aynı şeyi nasıl yapardı?
Petar Vasilev

bir şey boşa zamanım: 'awk NOT ile kullanmalısınız "
cn123h

6

Belki bir crontab'da böyle uzun süre çalışan komutu çalıştırın?

timeout -k 300 command

5

Önceki her iki yanıttan da yararlanan kill betiğimin sürümü:

#!/bin/bash

#Email to send report
MY_EMAIL="example@email.com"

#Process name to kill
NAME_KILL="php"

#UID to kill
UID_KILL=33.

#Time in seconds which the process is allowed to run
KILL_TIME=60

KILL_LIST=()
EMAIL_LIST=()
while read PROC_UID PROC_PID PROC_ETIMES PROC_ETIME PROC_COMM PROC_ARGS; do
    if [ $PROC_UID -eq $UID_KILL -a "$PROC_COMM" == "$NAME_KILL" -a $PROC_ETIMES -gt $KILL_TIME ]; then
    KILL_LIST+=("$PROC_PID");
    MSG="Killing '$PROC_ARGS' which runs for $PROC_ETIME";
    EMAIL_LIST+=("$MSG");
    echo "$MSG";
    fi
done < <(ps eaxo uid,pid,etimes,etime,comm,args | tail -n+2)
if [ ${#KILL_LIST[*]} -gt 0 ]; then
    kill -9 ${KILL_LIST[@]}
    printf '%s\n' "${EMAIL_LIST[@]}" | mail -s "Long running processes killed" $MY_EMAIL
fi

İşlemi UID, NAME ile filtreler ve yürütme süresi sınırı aşarsa işlemleri öldürür ve raporu e-postaya gönderir. Bu e-postaya ihtiyacınız yoksa - sadece son satıra yorum yapabilirsiniz.


2

Çözümü bu sayfada buldum: http://www.directadmin.com/forum/showthread.php?t=26179

Boş bir dosya oluşturun ve onu killlongproc.sh olarak adlandırın.

Bunu kopyala:

#!/bin/bash
# This script will kill process which running more than X hours
# egrep: the selected process; grep: hours
PIDS="`ps eaxo bsdtime,pid,comm | egrep "spamd|exim|mysqld|httpd" | grep " 1:" | awk '{print $2}'`"

# Kill the process
echo "Killing spamd, exim, mysqld and httpd processes running more than one hour..."
for i in ${PIDS}; do { echo "Killing $i"; kill -9 $i; }; done;

Dur bu içinde senin cronjob

15 * * * * * root /{directory}/./killongproc.sh

4
Bunu yapmak genellikle kötü bir fikirdir. Gerçekten hangi problemi çözmeye çalışıyorsun? Ayrıca, kill -9işlemlere çıkmadan önce zarif bir temizlik yapma şansı vermediğinden kullanmamalısınız .
sonraki duyuruya kadar duraklatıldı.

1
Bu, bir miktar gerçek zamanlı çalışan işlemleri (örneğin 1 saatten önce başlayan) değil, bir miktar CPU zamanı (kullanıcı + sistem) tüketen işlemleri öldürür.
Marki555

2

Burada istediğinizi yapmak için değiştirebileceğiniz bir komut dosyası var .

EDIT aşağıdaki komut dosyasını ekledi

#!/bin/bash
#
#Put the UID to kill on the next line
UID_KILL=1001

#Put the time in seconds which the process is allowed to run below
KILL_TIME=300

KILL_LIST=`{
ps -eo uid,pid,lstart | tail -n+2 |
    while read PROC_UID PROC_PID PROC_LSTART; do
        SECONDS=$[$(date +%s) - $(date -d"$PROC_LSTART" +%s)]
        if [ $PROC_UID -eq $UID_KILL -a $SECONDS -gt $KILL_TIME ]; then
        echo -n "$PROC_PID "
        fi
     done 
}`

if [[ -n $KILL_LIST ]]
then
        kill $KILL_LIST
fi

Bunu değiştirmek için yeterli bilgim yok, bu yüzden sana soruyorum

2
Çok karışık. İşlem başlangıcından bu yana geçen süreyi doğrudan göstermek için etimesof sütununu kullanabilirsiniz ps(başlangıç ​​zamanından itibaren hesaplamaya gerek yoktur).
Marki555

@ Marki555 evet bu doğru. Ancak, sürümleri olan sistemlerde (yalnızca ) psdesteklenmiyorsa , bu harika bir alternatiftir. Sadece üst cevap bana bir hata verdiğinde kullandımetimesetimeps
mike

0

Benzer bir görevi çözmek zorundaydım ve bir senaryoya ihtiyacı yok. Yürütülebilir "THECOMMAND" işlemlerini sonlandırmak (sinyal SIGTERM) için:

killall -u $USER --older-than 5m THECOMMAND

Geçerli kullanıcı -u $USERiçin kısıtlama, yalnızca diğer kullanıcılar da "THECOMMAND" çalıştırıyorsa gereksiz hata iletilerinden kaçınmak için gereklidir. Kendi kullanıcı crontab'ınızda aşağıdakileri girersiniz:

*/5 * * * *     killall -u $USER --older-than 5m THECOMMAND

Sistem crontab'ında (kullanıcı 'kökü') aşağıdakileri eklersiniz:

*/5 * * * *     killall --older-than 5m THECOMMAND

İşlemleri sonlandırmak (SIGTERM) yerine öldürmek (SIGKILL) istiyorsanız --signal SIGKILL, parametrelere ekleyerek SIGKILL sinyalini açıkça gönderin . Sistem crontab örneği:

*/5 * * * *     killall --older-than 5m --signal SIGKILL THECOMMAND

-4

Httpd için

ps eaxo pid, zaman, iletişim | kuyruk -n + 2 | grep 'httpd' | awk 'substr (0,9,1 $)> 0' | awk '{print $ 1}'

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.