最近做系統維護的時候,發現系統裏面總有那麼幾個進程的內存佔用量不斷的在往上漲,直接導致整個系統崩潰。因爲該服務器上同時還運行着其他幾個服務進程,爲了不讓其受到影響,就寫了個shell腳本,發現有進程的內存佔用率達到上限時,就將其殺死。
該腳本可以既可以根據指定的進程號進行監控,也可以根據正則表達式指定進程名進行監控。
具體代碼如下:
#! /bin/bash
PNAME=
PID=
MEM=
SEC=1
USAGE="$(basename $0) -[n 進程名] -[p 進程ID] -[s 監視間隔時間(單位:秒)] -[m 內存佔用上限(單位:字節,可以通過k,m,g,K,M,G,%指定單位)]"
while getopts n:p:s:m: OPT
do
case $OPT in
n)PNAME=$OPTARG
;;
p)PID=$OPTARG
;;
s)SEC=$OPTARG
;;
m)MEM=$OPTARG
;;
\?) echo $USAGE >&2;exit 1
;;
esac
done
echo $MEM|grep ^[0-9,.]*[0-9,k,m,g,K,M,G,%]$ >/dev/null
if [ $? -gt 0 ];then
echo "$MEM詞法錯誤" >&2
echo $USAGE >&2
exit 1
fi
MEM=$(echo $MEM|tr "[A-Z]" "[a-z]")
len=${#MEM}
unit=$(echo $MEM|cut -c $len)
case $unit in
k)
MEM=$(echo $MEM|cut -c 1-$[len-1])
MEM=$[MEM*1024]
;;
m)
MEM=$(echo $MEM|cut -c 1-$[len-1])
MEM=$[MEM*1024*1024]
;;
g)
MEM=$(echo $MEM|cut -c 1-$[len-1])
MEM=$[MEM*1024*1024*1024]
;;
%)
MEM=$(echo $MEM|cut -c 1-$[len-1])
;;
\?)
;;
esac
while true;do
date
if [ -n "$PID" ];then
ents=$(ps -e -o pid= -o vsz= -o pmem= -o pcpu= -o comm=|grep ^$PID)
elif [ -n "$PNAME" ];then
ents=$(ps -e -o pid= -o vsz= -o pmem= -o pcpu= -o comm=|grep $PNAME$)
else
echo "指定進程檢索條件">&2
echo $USAGE >&2
exit 1
fi
if [ -z "$ents" ];then
echo "沒有符合檢索條件的進程"
exit 0
fi
fields=($ents)
echo "符合檢索條件的進程信息:"
echo "【PID】 【VSZ(單位:k)】 【PMEM】 【PCPU】 【COMM】"
for ((i=0; i<${#fields[@]};i++))
do
printf " ${fields[$i]} "
if [ $[ i%5 ] -eq 4 ];then
printf \\n
fi
done
#按照內存的佔用率進行監控
if [ $unit == "%" ];then
pos=2
pmem=${fields[$pos]}
while [ -n "$pmem" ];do
echo "$pmem $MEM"|awk '($1>=$2){exit 1}'
if [ $? -eq 1 ];then
pid=${fields[$[pos-2]]}
comm=${fields[$[pos+2]]}
echo "殺死$pid:$comm進程【內存佔用率$pmem>=$MEM】"
kill -9 $pid
fi
pos=$[pos+5]
pmem=${fields[$pos]}
done
else
#按照內存的佔用量進行監控
pos=1
vsz=${fields[$pos]}
while [ -n "$vsz" ];do
vsz=$[vsz*1024]
if [ $vsz -ge $MEM ];then
pid=${fields[$[pos-1]]}
comm=${fields[$[pos+3]]}
echo "殺死$pid:$comm進程的【內存佔用數量$vsz>=$MEM】"
kill -9 $pid
fi
pos=$[pos+5]
vsz=${fields[$pos]}
done
fi
echo ""
if [ $SEC -gt 0 ];then
sleep $SEC
else
exit 0
fi
done