Ho bisogno del comando per uccidere i processi in esecuzione da almeno 5 minuti per un determinato processo.
Dovrò eseguire quel comando ogni cinque minuti circa.
Grazie mille !
(il sistema è Centos5)
Ho bisogno del comando per uccidere i processi in esecuzione da almeno 5 minuti per un determinato processo.
Dovrò eseguire quel comando ogni cinque minuti circa.
Grazie mille !
(il sistema è Centos5)
Risposte:
kill -9 $(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print $2}}')
dove "procname" è un nome di processo e 300 è la soglia del tempo di esecuzione
$(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print "kill "$2}}')
è un po 'più fluido, ma la risposta è comunque ottima
La mia versione di kill script, sfruttando entrambe le risposte precedenti:
#!/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
Filtra i processi in base a UID, NAME e se il tempo di esecuzione supera il limite: termina i processi e invia un rapporto via e-mail. Se non hai bisogno di quell'email, puoi semplicemente commentare l'ultima riga.
Ho trovato la soluzione in questa pagina: http://www.directadmin.com/forum/showthread.php?t=26179
Crea un file vuoto e chiamalo killlongproc.sh
#!/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;
Smetti di farlo nel tuo cronjob
15 * * * * * root /{directory}/./killongproc.sh
kill -9
poiché non dà ai processi la possibilità di fare una pulizia graziosa prima di uscire.
C'è uno script qui che puoi modificare per fare quello che vuoi.
EDIT ha aggiunto lo script di seguito
#!/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
etimes
di ps
per mostrare direttamente i secondi trascorsi dall'inizio del processo (non è necessario calcolarlo dall'inizio).
ps
che non supportano etimes
(solo etime
) questa è un'ottima alternativa. L'ho usato solo quando la risposta migliore mi ha dato un errore daps
Ho dovuto risolvere un compito simile e non ha bisogno di una sceneggiatura. Per terminare i processi (signal SIGTERM) dell'eseguibile "THECOMMAND":
killall -u $USER --older-than 5m THECOMMAND
La limitazione per l'utente corrente -u $USER
è necessaria solo per evitare messaggi di errore non necessari se anche altri utenti eseguono "THECOMMAND". Nel tuo crontab utente inseriresti quanto segue:
*/5 * * * * killall -u $USER --older-than 5m THECOMMAND
In un crontab di sistema (utente 'root') dovresti aggiungere quanto segue:
*/5 * * * * killall --older-than 5m THECOMMAND
Se si desidera eliminare (SIGKILL) i processi anziché terminarli (SIGTERM), inviare esplicitamente il segnale SIGKILL aggiungendo --signal SIGKILL
ai parametri. Esempio per un crontab di sistema:
*/5 * * * * killall --older-than 5m --signal SIGKILL THECOMMAND
-9
essere un po 'più amichevole con i miei processi e ho aggiunto ungrep -v defunct |
precedenteawk
come altrimenti, come potresti vedereprocname <defunct>
nel tuo output, il che renderebbe il comando awk non restituire un PID valido. E questo romperebbe il comando di uccisione.