Chinaunix首页 | 论坛 | 博客
  • 博客访问: 103674697
  • 博文数量: 19283
  • 博客积分: 9968
  • 博客等级: 上将
  • 技术积分: 196062
  • 用 户 组: 普通用户
  • 注册时间: 2007-02-07 14:28
文章分类

全部博文(19283)

文章存档

2011年(1)

2009年(125)

2008年(19094)

2007年(63)

分类:

2008-04-18 23:29:57

作者:styr  出处:Unix爱好者家园unix-cd.com   
有时scounix系统可能会有某些进程异常后不能自动终止,可能会导致系统响应缓慢或影响效率,可调用本脚本作简单的检测,查找这些异常进程并可选择性的清除或强行签退该进程的终端

[code]#!/bin/ksh
#查找超时进程并清除的脚本 V060407
#四川省乐山市沙湾区邮政局 宋 涛
#查找占用CPU时间的非root或非系统的进程和僵尸进程,并选择性的清除

killpid()
{
pid=$1  
awk '$1=="'$pid'" {print $4,$5,$6}' $tmpfile | read ktty kpid ktime
while :
do
echo -n "\n\n       是否清除 $ktty 终端上占用CPU时间 $ktime 秒的 $kpid 进程?(y/n): "
read yn
[ -z "$yn" ] && return
case $yn  in
q|Q) exit 0 ;
n|N) return ;
y|Y) break ;
*) echo "\n       输入错误,请重新输入"  read  continue ;
esac
done
kill -9 $kpid >/dev/null 2>&1
[  $? -eq 0 ] && echo "\n       清除 $kpid 进程 成功\n" \
|| echo "\n       清除 $kpid 进程 失败\n"
"$fuser" != "n" -a "&ktty" != "?" -a -x /etc/fuser ] && /etc/fuser -k /dev/$ktty >/dev/null 2>&1 
#清除超时进程后终端也可能会死锁,在此使用fuser清除终端所有进程,即强行签退该终端
echo "\n       请按任意键返回\n"  read 
}

tput bold
tmpfile=/tmp/$$
echonum=5
trap 'tput sgr0; rm -rf $tmpfile 2>/dev/null  echo  exit ' 0 1 2 3 15
if [ -n "$1" ] 
then 
[ $1 = "-h" ] && { printf "

         查找并清除占用CPU时间超长的进程
      
 调用命令行: $(basename $0) [ -h ] [ -k ]
              其中: -h 调用本帮助
             -k 只清除进程而不签退终端
    因某些情况下清除终端的超时进程后终端
 可能会死锁,故默认为清除指定进程的同时强
 行签退该终端(系统必须正常存在/etc/fuser)
    注:本脚本只能由root用户调用,功能为查
 找非root和非系统进程的占用CPU时间前${echonum}个
        进程(排除占用时间0的进程),通常超时过长的
        进程可能会导致系统响应缓慢,降低系统效率
        甚至导致系统崩溃,故感觉系统反应异常时可
        调用此脚本检查

"  exit 0  }
[ $1 = "-k" ] && fuser="n" 
fi
[ $LOGNAME != root ] && { echo "Sorry ! 本 脚 本 只 能 由 root 操 作 !\n\n"  exit 1  }

while :
do
clear
ps -efl | awk 'NR!=1 && $14!="00:00:00" && ( $3!="root" && $13!="?" || $2=="Z") \
{cputime=time($14)  print $2,$3,$13,$4,cputime,$12,$15,$16,$17,$18} 
function time(ot)
{
split(ot,var,":")
return var[1]*3600+var[2]*60+var[3]
}' | sort -nr +4 -5 | head -$echonum | \
awk 'BEGIN{printf("\n%35s\n\n%-5s%-6s%-10s%-10s%-8s%-10s%-10s%s\n"),
"超 时 进 程 表","序号","状态","用户名","终端号","PID","占用时间","开始时间","进程"}
{state=statetest($1); printf("\n%-5s%-6s%-10s%-10s%-8s%-10s%-10s%s %s %s %s\n"),
NR,state,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11}
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 "中间"
}' > $tmpfile
"$(awk '$1==1 {print $8}' $tmpfile)" ] && cat $tmpfile || { echo "\n       未找到当前系统的超时进程 !\n"  exit 0  }
echo  -n "\n       请输入欲清除的进程序号\n       回车默认序号为 1\n       r -- 重测  q -- 退出 : "
read yn 
[ -z "$yn" ] && yn=1 
case $yn in
q|Q) exit 0 ;
r|R) continue ;
esac 
"$(echo $yn|sed 's/[0-9 ]//g')" ] && { echo "\n       输入错误,请重新输入"  read  continue  }
for pid in $yn
do
"$(awk '$1=="'$pid'"  {print}' $tmpfile)" ] && killpid $pid || { echo "\n       无此序号,请重新输入"  read  continue  }
done
done

[/code]
阅读(476) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~