首页 > 代码库 > 使用Shell脚本对Linux系统和进程资源进行监控

使用Shell脚本对Linux系统和进程资源进行监控

ShellLinux脚本
摘要:Shell语言对于接触Linux的人来说都比较熟悉,它是系统的用户界面,提供了用户与内核进行交互操作的一种接口。本文我们以Bash做为实例总结了使用Shell对系统和进程资源进行监控的一些内容,希望对您能有帮助。

Shell语言对于接触Linux的人来说都比较熟悉,它是系统的用户界面,提供了用户与内核进行交互操作的一种接口。它接收用户输入的命 令并把它送入内核去执行。实际上Shell是一个命令解释器,它解释由用户输入的命令并且把它们送到内核。它没有一般编程语言的“编译 - 链接 - 运行”过程。不仅如此,Shell有自己的编程语言用于对命令的编辑,它允许用户编写由shell命令组成的程序。Shell编程语言具有普通编程语言的 很多特点,比如它也有循环结构和分支控制结构等,用这种编程语言编写的Shell程序与其他应用程序具有同样的效果。当然,Shell功能也是很强大的。 Shell有多种类型,其中最常用的几种是Bourne shell(sh)、C shell(csh)和 Korn shell(ksh)三种。shell各有优缺点,Linux操作系统缺省的shell一般是Bourne Again shell,它是Bourne shell的扩展,简称Bash。Bash的命令语法是Bourne shell命令语法的超集,并且在Bourne shell的基础上增加、增强了很多特性。在这里,我们以Bash做为实例总结了使用Shell对系统和进程资源进行监控的一些内容,希望对您能有帮助。 

检查进程是否存在

在对进程进行监控时,我们一般需要得到该进程的ID,进程ID是进程的唯一标识,但是有时可能在服务器上不同用户下运行着多个相同进程名的进程,下 面的函数GetPID给出了获取指定用户下指定进程名的进程ID功能(目前只考虑这个用户下启动一个此进程名的进程),它有两个参数为用户名和进程名,它 首先使用ps查找进程信息,同时通过grep过滤出需要的进程,最后通过sed和awk查找需要进程的ID值(此函数可根据实际情况修改,比如需要过滤其 它信息等)。

清单1.对进程进行监控

  1. function GetPID #User #Name  
  2.  
  3. {  
  4.  
  5. PsUser=$1  
  6.  
  7. PsName=$2  
  8.  
  9. pid=`ps -u $PsUser|grep $PsName|grep -v grep|grep -v vi|grep -v dbx\n  
  10.  
  11. |grep -v tail|grep -v start|grep -v stop |sed -n 1p |awk ‘{print $1}‘`  
  12.  
  13. echo $pid  
  14.  
  15. }  
  16.  

示例演示:

1)源程序(例如查找用户为root,进程名为CFTestApp的进程 ID)

  1. PID=`GetPID root CFTestApp`  
  2.  
  3. echo $PID 

2)结果输出

  1. 11426  
  2.  
  3. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:11426为root用户下的CFTestApp程序的进程ID。

4)命令介绍

1.ps:查看系统中瞬间进程信息。

参数:-u<用户识别码>列出属于该用户的程序的状况,也可使用用户名称来指定。

-p<进程识别码>指定进程识别码,并列出该进程的状况。

-o指定输出格式

2.grep:用于查找文件中符合字符串的当前行。

参数:-v反向选择,亦即显示出没有‘搜寻字符串’内容的那一行。

3.sed:一个非交互性文本编辑器,它编辑文件或标准输入导出的文件,一次只能处理一行内容。

参数:-n读取下一个输入行,用下一个命令处理新的行而不是用第一个命令。

p标志打印匹配行

4.awk:一种编程语言,用于在linux/unix下对文本和数据进行处理。数据可以来自标准输入、一个或多个文件,或其它命令的输出。它支持用户自

定义函数和动态正则表达式等先进功能,是linux/unix下的一个强大编程工具。它在命令行中使用,但更多是作为脚本来使用。awk的处理文本 和数据的方式:它逐行扫描文件,从第一行到最后一行,寻找匹配的特定模式的行,并在这些行上进行你想要的操作。如果没有指定处理动作,则把匹配的行显示到 标准输出(屏幕),如果没有指定模式,则所有被操作所指定的行都被处理。

参数:-F fs or –field-separator fs:指定输入文件折分隔符,fs是一个字符串或者是一个正则表达式,如-F:。

有时有可能进程没有启动,下面的功能是检查进程ID是否存在,如果此进程没有运行输出:

  1. The process does not exist.  
  2. # 检查进程是否存在  
  3. if [ "-$PID" == "-" ]  
  4. then  
  5. {  
  6. echo "The process does not exist."  
  7. }  
  8. fi 

检测进程CPU利用率

在对应用服务进行维护时,我们经常遇到由于CPU过高导致业务阻塞,造成业务中断的情况。CPU过高可能由于业务量过负荷或者出现死循环等异常情 况,通过脚本对业务进程CPU进行时时监控,可以在CPU利用率异常时及时通知维护人员,便于维护人员及时分析,定位,以及避免业务中断等。下面的函数可 获得指定进程ID的进程CPU利用率。它有一个参数为进程ID,它首先使用ps查找进程信息,同时通过grep -v过滤掉%CPU行,最后通过awk查找CPU利用百分比的整数部分(如果系统中有多个CPU,CPU利用率可以超过100%)。

清单2.对业务进程CPU进行实时监控

  1. function GetCpu  
  2.  
  3. {  
  4.  
  5. CpuValue=http://www.mamicode.com/`ps -p $1 -o pcpu |grep -v CPU | awk ‘{print $1}‘ | awk - F. ‘{print $1}‘`
  6.  
  7. echo $CpuValue  
  8.  

下面的功能是通过上面的函数GetCpu获得此进程的CPU利用率,然后通过条件语句判断CPU利用率是否超过限制,如果超过80%(可以根据实际情况进行调整),则输出告警,否则输出正常信息。

清单3.判断CPU利用率是否超过限制

  1. function CheckCpu  
  2.  
  3. {  
  4.  
  5. PID=$1  
  6.  
  7. cpu=`GetCpu $PID`  
  8.  
  9. if [ $cpu -gt 80 ]  
  10.  
  11. then  
  12.  
  13. {  
  14.  
  15. echo “The usage of cpu is larger than 80%”  
  16.  
  17. }  
  18.  
  19. else  
  20.  
  21. {  
  22.  
  23. echo “The usage of cpu is normal”  
  24.  
  25. }  
  26.  
  27. fi  
  28.  

示例演示:

1)源程序(假设上面已经查询出CFTestApp的进程ID为11426)

  1. CheckCpu 11426 

2)结果输出

  1. The usage of cpu is 75  
  2.  
  3. The usage of cpu is normal  
  4.  
  5. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:CFTestApp程序当前的CPU使用为75%,是正常的,没有超过80%的告警限制。

检测进程内存使用量

在对应用服务进行维护时,也经常遇到由于内存使用过大导致进程崩溃,造成业务中断的情况(例如32位程序可寻址的最大内存空间为4G,如果超出将申 请内存失败,同时物理内存也是有限的)。内存使用过高可能由于内存泄露,消息堆积等情况,通过脚本对业务进程内存使用量进行时时监控,可以在内存使用量异 常时及时发送告警(例如通过短信),便于维护人员及时处理。下面的函数可获得指定进程ID的进程内存使用情况。它有一个参数为进程ID,它首先使用ps查 找进程信息,同时通过grep -v过滤掉VSZ行,然后通过除1000取以兆为单位的内存使用量。

清单4.对业务进程内存使用量进行监控

  1. function GetMem  
  2.  
  3. {  
  4.  
  5. MEMUsage=`ps -o vsz -p $1|grep -v VSZ`  
  6.  
  7. (( MEMUsage /= 1000))  
  8.  
  9. echo $MEMUsage  
  10.  

下面的功能是通过上面的函数GetMem获得此进程的内存使用,然后通过条件语句判断内存使用是否超过限制,如果超过1.6G(可以根据实际情况进行调整),则输出告警,否则输出正常信息。

清单5.判断内存使用是否超过限制

  1. mem=`GetMem $PID`  
  2.  
  3. if [ $mem -gt 1600 ]  
  4.  
  5. then  
  6.  
  7. {  
  8.  
  9. echo “The usage of memory is larger than 1.6G”  
  10.  
  11. }  
  12.  
  13. else  
  14.  
  15. {  
  16.  
  17. echo “The usage of memory is normal”  
  18.  
  19. }  
  20.  
  21. fi 

示例演示:

1)源程序(假设上面已经查询出CFTestApp的进程ID为11426)

  1. mem=`GetMem 11426`  
  2.  
  3. echo "The usage of memory is $mem M"  
  4.  
  5. if [ $mem -gt 1600 ]  
  6.  
  7. then  
  8.  
  9. {  
  10.  
  11. echo "The usage of memory is larger than 1.6G"  
  12.  
  13. }  
  14.  
  15. else  
  16.  
  17. {  
  18.  
  19. echo "The usage of memory is normal"  
  20.  
  21. }  
  22.  
  23. fi 

2)结果输出

  1. The usage of memory is 248 M  
  2.  
  3. The usage of memory is normal  
  4.  
  5. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:CFTestApp程序当前的内存使用为248M,是正常的,没有超过1.6G的告警限制。

检测进程句柄使用量

在对应用服务进行维护时,也经常遇到由于句柄使用过量导致业务中断的情况。每个平台对进程的句柄使用都是有限的,例如在Linux平台,我们可以使 用ulimit – n 命令(open files (-n) 1024)或者对/etc/security/limits.conf的内容进行查看,得到进程句柄限制。句柄使用过高可能由于负载过高,句柄泄露等情 况,通过脚本对业务进程句柄使用量进行时时监控,可以在异常时及时发送告警(例如通过短信),便于维护人员及时处理。下面的函数可获得指定进程ID的进程 句柄使用情况。它有一个参数为进程ID,它首先使用ls输出进程句柄信息,然后通过wc -l统计输出句柄个数。

  1. function GetDes  
  2.  
  3. {  
  4.  
  5. DES=`ls /proc/$1/fd | wc -l`  
  6.  
  7. echo $DES  
  8.  

下面功能是通过上面的函数GetDes获得此进程的句柄使用量,然后通过条件语句判断句柄使用是否超过限制,如果超过900(可以根据实际情况进行调整)个,则输出告警,否则输出正常信息。

  1. des=` GetDes $PID`  
  2.  
  3. if [ $des -gt 900 ]  
  4.  
  5. then  
  6.  
  7. {  
  8.  
  9. echo “The number of des is larger than 900”  
  10.  
  11. }  
  12.  
  13. else  
  14.  
  15. {  
  16.  
  17. echo “The number of des is normal”  
  18.  
  19. }  
  20.  
  21. fi 

示例演示:

1)源程序(假设上面查询出CFTestApp的进程ID为11426)

  1. des=`GetDes 11426`  
  2.  
  3. echo "The number of des is $des"  
  4.  
  5. if [ $des -gt 900 ]  
  6.  
  7. then  
  8.  
  9. {  
  10.  
  11. echo "The number of des is larger than 900"  
  12.  
  13. }  
  14.  
  15. else  
  16.  
  17. {  
  18.  
  19. echo "The number of des is normal"  
  20.  
  21. }  
  22.  
  23. fi 

2)结果输出

  1. The number of des is 528  
  2.  
  3. The number of des is normal  
  4.  
  5. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:CFTestApp程序当前的句柄使用为528个,是正常的,没有超过900个的告警限制。

4)命令介绍

wc:统计指定文件中的字节数、字数、行数,并将统计结果显示输出。

参数:-l统计行数。

-c统计字节数。

-w统计字数。

使用Shell对系统资源进行监控

查看某个TCP或UDP端口是否在监听

端口检测是系统资源检测经常遇到的,特别是在网络通讯情况下,端口状态的检测往往是很重要的。有时可能进程,CPU,内存等处于正常状态,但是端口 处于异常状态,业务也是没有正常运行。下面函数可判断指定端口是否在监听。它有一个参数为待检测端口,它首先使用netstat输出端口占用信息,然后通 过grep, awk,wc过滤输出监听TCP端口的个数,第二条语句为输出UDP端口的监听个数,如果 TCP与UDP端口监听都为0,返回0,否则返回1.

清单6.端口检测

  1. function Listening  
  2.  
  3. {  
  4.  
  5. TCPListeningnum=`netstat -an | grep ":$1 " | \n  
  6.  
  7. awk ‘$1 == "tcp" && $NF == "LISTEN" {print $0}‘ | wc -l`  
  8.  
  9. UDPListeningnum=`netstat -an|grep ":$1 " \n  
  10.  
  11. |awk ‘$1 == "udp" && $NF == "0.0.0.0:*" {print $0}‘ | wc -l`  
  12.  
  13. (( Listeningnum = TCPListeningnum + UDPListeningnum ))  
  14.  
  15. if [ $Listeningnum == 0 ]  
  16.  
  17. then  
  18.  
  19. {  
  20.  
  21. echo "0"  
  22.  
  23. }  
  24.  
  25. else  
  26.  
  27. {  
  28.  
  29. echo "1"  
  30.  
  31. }  
  32.  
  33. fi  
  34.  

示例演示:

1)源程序(例如查询8080端口的状态是否在监听)

  1. isListen=`Listening 8080`  
  2.  
  3. if [ $isListen -eq 1 ]  
  4.  
  5. then  
  6.  
  7. {  
  8.  
  9. echo "The port is listening"  
  10.  
  11. }  
  12.  
  13. else  
  14.  
  15. {  
  16.  
  17. echo "The port is not listening"  
  18.  
  19. }  
  20.  
  21. fi 

2)结果输出

  1. The port is listening  
  2.  
  3. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:这个Linux服务器的8080端口处在监听状态。

4)命令介绍

netstat:用于显示与IP、TCP、UDP和ICMP协议相关的统计数据,一般用于检验本机各端口的网络连接情况。

参数:-a显示所有连线中的Socket。

-n直接使用IP地址,而不通过域名服务器。

下面的功能也是检测某个TCP或者UDP端口是否处在正常状态。

  1. tcp: netstat -an|egrep $1 |awk ‘$6 == "LISTEN" && $1 == "tcp" {print $0}‘  
  2.  
  3. udp: netstat -an|egrep $1 |awk ‘$1 == "udp" && $5 == "0.0.0.0:*" {print $0}‘ 

命令介绍

egrep:在文件内查找指定的字符串。egrep执行效果如rep -E,使用的语法及参数可参照grep指令,与grep不同点在于解读字符串的方法,egrep是用扩展的正则表达式语法来解读,而grep则用基本的正 则表达式语法,扩展的正则表达式比基本的正则表达式有更完整的表达规范。

查看某个进程名正在运行的个数

有时我们可能需要得到服务器上某个进程的启动个数,下面的功能是检测某个进程正在运行的个数,例如进程名为CFTestApp。

  1. Runnum=`ps -ef | grep -v vi | grep -v tail | grep "[ /]CFTestApp" | grep -v grep | wc -l 

检测系统CPU负载

在对服务器进行维护时,有时也遇到由于系统CPU(利用率)负载过量导致业务中断的情况。服务器上可能运行多个进程,查看单个进程的CPU都是正常 的,但是整个系统的CPU负载可能是异常的。通过脚本对系统CPU负载进行时时监控,可以在异常时及时发送告警,便于维护人员及时处理,预防事故发生。下 面的函数可以检测系统CPU使用情况 . 使用vmstat取5次系统CPU的idle值,取平均值,然后通过与100取差得到当前CPU的实际占用值。

  1. function GetSysCPU  
  2.  
  3. {  
  4.  
  5. CpuIdle=`vmstat 1 5 |sed -n ‘3,$p‘ \n  
  6.  
  7. |awk ‘{xx = x + $15} END {print x/5}‘ |awk -F. ‘{print $1}‘  
  8.  
  9. CpuNum=`echo "100-$CpuIdle" | bc`  
  10.  
  11. echo $CpuNum  
  12.  

示例演示:

1)源程序

  1. cpu=`GetSysCPU`  
  2.  
  3. echo "The system CPU is $cpu"  
  4.  
  5. if [ $cpu -gt 90 ]  
  6.  
  7. then  
  8.  
  9. {  
  10.  
  11. echo "The usage of system cpu is larger than 90%"  
  12.  
  13. }  
  14.  
  15. else  
  16.  
  17. {  
  18.  
  19. echo "The usage of system cpu is normal"  
  20.  
  21. }  
  22.  
  23. fi 

2)结果输出

  1. The system CPU is 87  
  2.  
  3. The usage of system cpu is normal  
  4.  
  5. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:当前Linux服务器系统CPU利用率为87%,是正常的,没有超过90%的告警限制。

4)命令介绍

vmstat:Virtual Meomory Statistics(虚拟内存统计)的缩写,可对操作系统的虚拟内存、进程、CPU活动进行监视。

参数:-n表示在周期性循环输出时,输出的头部信息仅显示一次。

检测系统磁盘空间

系统磁盘空间检测是系统资源检测的重要部分,在系统维护维护中,我们经常需要查看服务器磁盘空间使用情况。因为有些业务要时时写话单,日志,或者临 时文件等,如果磁盘空间用尽,也可能会导致业务中断,下面的函数可以检测当前系统磁盘空间中某个目录的磁盘空间使用情况。输入参数为需要检测的目录名,使 用df输出系统磁盘空间使用信息,然后通过grep和awk过滤得到某个目录的磁盘空间使用百分比。

  1. function GetDiskSpc  
  2.  
  3. {  
  4.  
  5. if [ $# -ne 1 ]  
  6.  
  7. then  
  8.  
  9. return 1  
  10.  
  11. fi  
  12.  
  13. Folder="$1$" 
  14.  
  15. DiskSpace=`df -k |grep $Folder |awk ‘{print $5}‘ |awk -F% ‘{print $1}‘  
  16.  
  17. echo $DiskSpace  
  18.  

示例演示:

1)源程序(检测目录为 /boot)

  1. Folder="/boot" 
  2.  
  3. DiskSpace=`GetDiskSpc $Folder`  
  4.  
  5. echo "The system $Folder disk space is $DiskSpace%"  
  6.  
  7. if [ $DiskSpace -gt 90 ]  
  8.  
  9. then  
  10.  
  11. {  
  12.  
  13. echo "The usage of system disk($Folder) is larger than 90%"  
  14.  
  15. }  
  16.  
  17. else  
  18.  
  19. {  
  20.  
  21. echo "The usage of system disk($Folder) is normal"  
  22.  
  23. }  
  24.  
  25. fi 

2)结果输出

  1. The system /boot disk space is 14%  
  2.  
  3. The usage of system disk(/boot) is normal  
  4.  
  5. [dyu@xilinuxbldsrv shell]$ 

3)结果分析

从上面的输出可见:当前此Linux服务器系统上/boot 目录的磁盘空间已经使用了14%,是正常的,没有超过使用90% 的告警限制。

4)命令介绍

df:检查文件系统的磁盘空间占用情况。可以利用该命令来获取硬盘被占用了多少空间,目前还剩下多少空间等信息。

参数:-k以k字节为单位显示。

总结

在Linux平台下,shell脚本监控是一个非常简单,方便,有效的对服务器,进程进行监控的方法,对系统开发以及进程维护人员非常有帮助。它不仅可以对上面的信息进行监控,发送告警,同时也可以监控进程的日志等等的信息,希望本文对大家有帮助。

使用Shell脚本对Linux系统和进程资源进行监控