首页 > 学技术 > 技术网文 > Linux Shell > 正文

[精华] [原创自动查杀超时或僵死的进程的脚本


来源 chinaunix.net 酷勤网整理

有时候前置机会出现死进程等,做了这个自动查杀的脚本,已在sco unix505中测试通过,如想测试,可ps -efl >file ,自行修改file里的进程状态及占用时间,再将脚本的输入源由ps -efl改为从file得到,屏敝 kill -9 $pid, 即可通过tty输出及日志文件观察到正确结果
请大家斧正.谢谢!
(如将此脚本加入crontab,时间自定,即可达到自动查杀超时或僵死的进程)

#!/bin/ksh

#自动查杀超时或僵死的进程的脚本   V050930
#crontab -e  
#0,5,10,15,20,25,30,40,45,50,55 * * * * /usr/bin/autokill.sh &  #设置为每5分钟检查一次超时进程
#为了安全保险起见,此版脚本的清除范围为:由终端启动的,占用CUP时间超过指定时间长度的,非root用户的进程或僵尸进程  ^_^

#检测参数
killlog="/tmp/kill.log"    #默认自动清除超时进程或僵死进程的日志
out=60                     # 默认的超时时间,以秒为单位,默认为60秒,范围为10秒--36000秒
trap 'rm /tmp/kill.tmp 2>/dev/null' 0 1 2 3 9 15
test $LOGNAME != root && { echo "Sorry ! 本 脚 本 只 能 由 root 操 作 !\n\n" ; exit 1 ; }
test "$out" || { echo "\n  超时时限不能为空\n" ; exit 1 ; }
test "$(echo $out | sed -n '/^[0-9][0-9]*$/p')" || { echo "\n  超时时限只能为整数值\n" ; exit 1 ; }
test $out -ge 10 -a $out -le 36000 || { echo "\n  超时时限范围为10秒--36000秒\n" ; exit 1 ; }

#查找超时或僵尸进程
ps -efl |awk -v outtest=$out '{ outtime=timetest($14) }
$2~/Z/ || ( $3!~/root/ && $13!~/\?/ && outtime=="outtime" ) \
{print $3,$4,$13,$2,$14,$15 }
function timetest(ot)
{
hour=substr(ot,1,2)
min=substr(ot,4,2)
sec=substr(ot,7,8)
if ( hour*3600+min*60+sec > outtest)
return "outtime"
else
return "good" 
} ' >/tmp/kill.tmp 2>/dev/null

#保存清除列表
if [ -s /tmp/kill.tmp ]
then
pass=0 
error=0
echo "\n清 除 时 间:  "$(date +%y/%m/%d-%H:%M:%S)"\n" >> $killlog
awk 'BEGIN{printf("%-8s%-8s%-8s%-7s%-10s%-30s\n"),"用户名","进程号","终端号","状态","占用时间","任务名"} 
{ state=statetest($4) ; printf("%-8s%-8s%-8s%-7s%-10s%-30s\n"),$1,$2,$3,state,$5,$6} END{print "\n"}
function statetest(test)
{  
 if (test=="S") return "睡眠"
 if (test=="R") return "运行"
 if (test=="Z") return "僵尸"
 if (test=="O") return "不存在"
 if (test=="B") return "等待"
 if (test=="T") return "停止"
 if (test=="I") return "中间"
}' /tmp/kill.tmp >> $killlog 2>/dev/null

#清除进程
for pid in $(awk '{print $2}' /tmp/kill.tmp |sort -rn) 
do 
kill -9 $pid  
test $? -eq 0 && \
{ echo "自动清除进程 $pid 成功" | awk '{printf("\n%-14s%-10s%-4s"),$1,$2,$3}' ; 
echo "自动清除进程 $pid 成功"   | awk '{printf("%-14s%-10s%-4s\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ;  pass=$((pass+1)) ; } || \
{ echo "自动清除进程 $pid 失败" | awk '{printf("\n%-14s%-10s%-4s"),$1,$2,$3}' ; 
echo "自动清除进程 $pid 失败"   | awk '{printf("%-14s%-10s%-4s\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ; error=$((error+1)) ; }
done

#保存最终统计结果
test $error -eq 0 && \
{ echo "此次共清除 ${pass} 个进程成功" | awk '{printf("\n\n%-14s%-4s%-10s\n\n"),$1,$2,$3}'
  echo "此次共清除 ${pass} 个进程成功" | awk '{printf("\n%-14s%-4s%-10s\n\n"),$1,$2,$3}' \
>> $killlog 2>/dev/null ; } || \
{ echo "此次共清除 ${pass} 个进程成功 ${error} 个进程失败" | \
awk '{printf("\n\n%-14s%-4s%-16s%-10s%-10s\n\n"),$1,$2,$3,$4,$5}' ; 
  echo "此次共清除 ${pass} 个进程成功 ${error} 个进程失败" | \
awk '{printf("\n\n%-14s%-4s%-16s%-10s%-10s\n\n"),$1,$2,$3,$4,$5}' >> $killlog 2>/dev/null ; }
fi




 寂寞烈火 回复于:2005-10-01 11:00:24

支持原创


 twf_cc 回复于:2005-10-01 11:43:25

nice script!


 alun123456 回复于:2005-10-01 11:52:36

系统不是有一个命令是idle


 styr 回复于:2005-10-01 12:25:10

下面是以前在坛里找到的脚本,只是感觉设置不太方便和不知道运行结果,就动手改进了一下。

#!/bin/ksh

#自动杀死UNIX僵死的进程
ps -ef | awk '{ print $1,$2,$7,$8 }' | \
awk '/[0-9][0-9]:[0-9][0-9]:[1-9][0-9]/ { print $1,$2,$3,$4 }' | \
awk '!/root/ { print "kill -9 " $2}' > /tmp/k_kill
chmod 777 /tmp/k_kill 
/tmp/k_kill 



sco unix505里没有idle这个命令,倒好像是有个系统参数,可以设置为终端N分钟无动作就outlogin的,和脚本实现的目的不同


 bingosek 回复于:2005-10-02 12:44:51

最好不要一开始就用-9,先用-15,sleep个3,5秒在检测一下状态,如果杀不掉在-9


 styr 回复于:2005-10-02 15:06:35

^_^. 指点的对,这样更安全。

kill -15 $pid

sleep 3
test "$(ps -efl | awk '$4=='"$pid"' {print }') " || kill -9 $pid



 我菜我怕谁 回复于:2005-10-03 09:38:56

支持


 bad_me 回复于:2005-10-11 20:04:11




 styr 回复于:2005-10-11 21:17:47

是不是有idle命令不清楚了,偶的sco没找到这个命令


 albcamus 回复于:2005-10-12 11:26:00

看不懂Shell。不过偶想问一下,僵尸进程是怎么杀掉的呢? 发送信号吗?可是它不接受信号啊


 styr 回复于:2005-10-12 11:40:57

僵尸进程也是有PID的


 albcamus 回复于:2005-10-12 11:44:42

引用:原帖由 "styr"]僵尸进程也是有PID的
 发表:


僵尸是有PID,可是它不会返回到用户态,这样就不会接受信号了呀。信号的递送都是发生在即将返回到用户态的时候。
如果是发送信号给它的父进程,父进程能撤消它,这个好象更合情些。


 styr 回复于:2005-10-12 12:51:27

既然是叫僵尸进程,那肯定就和正常进程结束是不一样,
如果相同了,那什么叫“僵尸”


 ha_ 回复于:2006-06-09 15:57:10

总的意思是杀掉process state为Z的进程?什么情况下会出现僵死进程呢?可否讨论一下?


 cuci 回复于:2006-06-09 15:59:47

引用:原帖由 ha_ 于 2006-6-9 15:57 发表
总的意思是杀掉process state为Z的进程?什么情况下会出现僵死进程呢?可否讨论一下? 



父亲完成任务在招孩子回家的时候,漏掉了一个,因此这个孩子就回不了家,最终变成僵尸了:mrgreen:


 231053469 回复于:2006-06-09 16:06:58

看懂一些
好啊!


 ha_ 回复于:2006-06-09 16:14:08

引用:原帖由 cuci 于 2006-6-9 15:59 发表
父亲完成任务在招孩子回家的时候,漏掉了一个,因此这个孩子就回不了家,最终变成僵尸了:mrgreen: 



呵呵,很形象的比喻。


 ha_ 回复于:2006-06-09 16:21:01

孩子一定要向父亲汇报情况
所以nohup就是把孩子的父亲指定为 init进程。是这样理解吧。


 waker 回复于:2006-06-09 16:28:36

能kill还叫zombie么? @@


 ha_ 回复于:2006-06-09 16:33:05

kill -9 也不能响应吗?
kill -9 1 会怎样?


 寂寞烈火 回复于:2006-06-09 16:50:09

引用:原帖由 ha_ 于 2006-6-9 16:33 发表
kill -9 也不能响应吗?
kill -9 1 会怎样? 


kill 掉1号进程?


 cuci 回复于:2006-06-09 16:50:32

可以kill掉吧,以前都是kill的


 huanghaojie 回复于:2006-06-09 18:45:57

引用:原帖由 albcamus 于 2005-10-12 11:26 发表
看不懂Shell。不过偶想问一下,僵尸进程是怎么杀掉的呢? 发送信号吗?可是它不接受信号啊 


看不懂SHELL也能做版主。


 entomology 回复于:2006-07-30 10:42:23

受益受益^_^,提点小意见,crontab里每5分种执行一次可以直接这样写,呵呵
*/5  * * * *




原文链接:http://bbs.chinaunix.net/viewthread.php?tid=621023
转载请注明作者名及原文出处



收藏本页到: