Linux 下使用Shell 脚本Kill进程并发送邮件通知

/ linux / 0 条评论 / 932浏览

Linux 下使用Shell 脚本Kill进程并发送邮件通知

需求说明
1.检测系统上正在运行的进程,如果存在进程运行占用内存达到2G或以上,则kill掉该进程
2. 发送邮件通知给被kill掉的服务的所属者和管理员并简单描述原因
3. 系统运行环境为CentOS
需求分析

在Linux上查看进程,我们可以使用命令ps 命令,另外我们需要知道每个进程所占用内存大小,已及该进程的拥有者,还有该进程的pid, 所以我们可以使用以下命令来实现:

root@zhany$ ps -e -o 'pid,rsz,user,uid,comm' --sort -rsz

pid 显示进程的pid
rsz 显示进程所使用内存的实际大小
user 该进程的拥有者
uid uid信息在后面的处理中没用使用到
comm 会在发送的邮件里面使用到
--sort 指定排序
-rsz 结果按照使用内存大小倒序排列

以上命令执行的结果如下:

1.png

目前的想法是将以上内容输出到文件,然后在后面读取文件中的每一行的数据拿到RSZ 这一列的数据与临界值进行比较,若该[RSZ]值大于临界值则拿改进程的pid, 使用kill -9 pid命令杀掉该进程,再拿到对应的user数据,根据user数据在user.properties文件中获取到用户的邮箱。
在CentOS上发送邮件可以使用mailx程序,使用以下命令在CentOS上安装该程序:

root@zhany$ yum install -y mailx

对mailx 进行配置,主要是在里面配置发件人的信息:

root@zhany$ vim /etc/mail.rc

在文件末尾添加一下配置信息(不同的邮箱需设置不同smtp协议,具体可自行查找mailx相关配置信息):

 ## sender's config
set from=xxx@sina.com smtp=smtp.sina.com
set smtp-auth-user=xxx@sina.com smtp-auth-password=(邮箱登录密码)
set smtp-auth=login

用于接收邮件的用户信息设置,由于不同的用户登录系统,运行的服务所对应的user不同,所以我们可以单独维护一个user.properties 文件,这是将此文件放置在/opt/user.properties 文件中,文件内容形式为:
user=email, 内容如下图:

2.png

脚本运行:

./kill.sh 1000    # 将杀掉占用内存大于1000KB的进程并通知给相应的人员
./kill.sh            # 将杀掉脚本默认设置的内存大于2G的进程

脚本源码如下:

#!/bin/bash
cmd=`ps -e -o 'pid,rsz,user,uid,comm' --sort -rsz`

====================================================================

设置管理员邮箱地址

admin="administrator@sina.com"

====================================================================

out=${cmd} file="/opt/rsz.txt" user_email="/opt/user.properties"

echo "$out" > $file

OLD_IFS="$IFS" IFS=" "

使用命令./kill.sh args执行, 如果args为空则使用默认设置, args 参数为整型, 单位为KB

默认使用内存大于2GB 则杀掉该进程

flag=$1 if [ ! "$flag" ]; then flag=2097152
fi

读取文件的每一行,跳过第一行

cat $file |awk 'NR>1' | while read line do OLD_IFS="$IFS" IFS=" " array=($line) #echo $array IFS=OLD_IFS for var in ${array[1]} do if [[ "$var"=~"^[a-zA-Z]+$" ]] ;then if [ $var -gt $flag ] ;then kill -9 ${array[0]} ## pid

            ## 获取用户邮箱作为邮件接收地址
            user=${array[2]}  ## user
            echo $user
            cat $user_email | while read line
            do
                OLD_IFS="$IFS"
                IFS="="
                arrs=($line)
                IFS=OLD_IFS
                for v in ${arrs[0]}
                do
                    if [ "$user" == "$v" ] ;then
                        to=${arrs[1]}
                        echo "$to"
                        echo "您好,您有一个服务${array[4]},运行内存达到 $var KB ,现在已被kill掉,请知晓! " | mail -s "系统通知" "$to" "$admin"    
                    fi
                done
            done
        fi
    fi
done

done


如何发送html页面,通过mailx 很简单,如果您的mailx命令支持-a(append header)选项:

$ mailx -a 'Content-Type: text/html' -s "my subject" user@gmail.com < email.html

如果不是,请尝试使用sendmail:

create a header file

$ cat mailheader

To: user@gmail.com

Subject: my subject

Content-Type: text/html

send

$ cat mailheader email.html | sendmail -t