在linux bash脚本中杀死给定用户正在运行超过5分钟的所有进程


18

我需要该命令来杀死给定进程至少5分钟以来一直在运行的进程。

我将不得不每五分钟运行一次该命令。

太感谢了 !

(系统是Centos5)

linux  bash 

Answers:


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

其中“ procname”是进程名称,而300是运行时间阈值


太棒了。我已经使用它,而不是-9让我的进程更友好,并在输出中添加了grep -v defunct |before awkprocname <defunct>这可能会使awk命令不返回有效的PID。这会破坏kill命令。
MichaelHärtl'16

我会说$(ps -eo comm,pid,etimes | awk '/^procname/ {if ($3 > 300) { print "kill "$2}}')稍微平滑一点,但答案还是不错的
Yevgen '18

@WhiteHat除了具有特定pid的进程外,将如何做同样的事情?
Petar Vasilev

浪费我时间的一件事是:应该使用'with awk NOT“
cn123h

6

也许在crontab中运行像这样的长时间运行的命令?

timeout -k 300 command

5

我的kill脚本版本,从先前的两个答案中受益:

#!/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

它按UID,NAME过滤进程,并且如果执行时间超出限制-杀死进程并将报告发送到电子邮件。如果您不需要该电子邮件-您可以在最后一行发表评论。


2

我在此页面上找到了解决方案:http : //www.directadmin.com/forum/showthread.php?t=26179

制作一个空文件,并将其命名为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;

停止在您的cronjob

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

4
这样做通常不是一个好主意。您到底要解决什么问题?另外,您不应该使用kill -9它,因为它不会使进程有机会在退出之前进行优美的清理。
暂停,直到另行通知。

1
这会杀死消耗了一定时间的CPU(用户+系统)的进​​程,而不是正在运行一定数量的实时(例如,在1小时之前启动)的进程。
Marki555 2014年

2

有一个脚本,在这里,你可以修改,做你想做什么。

编辑在下面添加了脚本

#!/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

我没有足够的知识来修改它,所以我要问你

2
太复杂。您可以使用etimesof 列ps直接显示自流程启动以来经过的秒数(无需从启动时间开始计算)。
Marki555 2014年

@ Marki555是的,这是正确的。但是ps,在不支持该版本的系统上etimes(仅支持etime),这是一个很好的选择。当最高答案给我一个错误时,我才用它ps
麦克

0

我不得不解决类似的任务,并且不需要脚本。用于终止可执行文件“ THECOMMAND”的(信号SIGTERM)过程:

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

-u $USER只有在其他用户也运行“ THECOMMAND”的情况下,才有必要限制当前用户,以避免产生不必要的错误消息。在您自己的用户crontab中,您将输入以下内容:

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

在系统crontab(用户'root')中,您将添加以下内容:

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

如果要终止(SIGKILL)进程而不是终止(SIGTERM)进程,请通过添加--signal SIGKILL参数来显式发送SIGKILL信号。系统crontab的示例:

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

-4

对于httpd

ps eaxo pid,时间,通讯| 尾-n + 2 | grep'httpd'| awk'substr($ 0,9,1)> 0'| awk'{print $ 1}'

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.