简单进程监控程序

简单进程监控程序

题目描述

作业题目:写一个 Shell 脚本来进行进程的死活监控

作业描述:此 Shell 脚本能检查配置文件中记录的进程是否在系统中运行。如果在系统中运行则显示进程ID(PID),如果不在运行则显示 DOWN 文字。

配置文件(check_procs.conf):

systemd
smbd
nmbd
#logd
sshd

脚本命名为check_proc.sh, 执行脚本后的输出结果:

systemd: 1 5241 31842
smbd: DOWN
nmbd: DOWN
sshd: 5025 31840 31857

要求:

  • 考虑各种错误场景的出错处理
  • 关键代码要有合理注释
  • 进行合理的函数功能封装

解题思路

题目的意图很明显,就是让我们读入配置文件,然后挨个判断文件中记录的进程是否在系统中运行,运行则给出 PID,否则显示 DOWN。根据输入和输出结果可以看出,注释掉的进程是不用判断的,直接略过。

核心的功能就是三步,读取文件、跳过注释、判断进程,最后将功能合理封装为函数运行即可。

详细编码实现

在编写代码之前,有一个非常重要的注意事项,Shell中的变量赋值是不能有空格的。比如我们要将给变量 a 赋值为5,应该写为 a=5,而不能是 a = 5。虽然加了空格会更美观,但是代码就不能按照预期运行了,所以赋值等号两边一定不要加空格!

1.判断进程

判断进程是程序最核心的功能,我们可以先进行进程判断,再将其他的功能加上。

使用非常典型的通过 grep 获取进程ID的方法,判断systemd 这个进程是否在运行。

program="systemd"	# 进程名称

#获取进程PID,为空则进程未启动
pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'`
if [ "${pid}" == "" ]
then
	echo "${program}: DOWN"
else
	echo -ne "${program}: "		# echo默认换行,-ne表示当前输出不换行
	echo ${pid}
fi
  • ps -ef ,显示所有的进程,e显示结果,f 显示完整格式
  • ps -ef | grep xxx ,把包括 xxx 这个关键字的进程都显示出来
  • grep -v grep,去除 grep 进程(即去除含有 xxx 关键字的这个grep查找进程本身)
  • awk ‘{print $2}’,提取结果的第二列数据(因为第二列正是进程的PID)

2.检查文件

方便起见,我们就将文件放在 shell 脚本的同级目录下。新建配置文件 check_procs.conf,将上面的配置文件示例全部写入

在脚本中编写判断文件是否存在的代码

fileName="check_procs.conf"			# 文件名
BASE_PATH=$(cd `dirname $0`; pwd)	# 获取当前目录

if [ ! -e "${BASE_PATH}/${fileName}" ]		# 判断当前目录下文件是否存在
then
	echo "文件不存在或无法读取"
	exit 0
fi
  • dirname $0,取得当前执行的脚本文件的父目录
  • cd ‘dirname $0’, 进入这个目录(切换当前工作目录)
  • pwd,显示当前工作目录(cd执行后的)

3.处理注释

读取文件,按每一行进行判断,line为变量,表示每一行的内容

判断当前行第一个字符是否为 #,如果是则当前行全部是注释,忽略即可

cat $fileName | while read line		# 读取文件,按行处理
do
	if [ "${line:0:1}" == "#" ]  	# 第一个字符为 ‘#’
	then
    		# 此处编写处理语句
	fi
done

可以看到,当前这个注释判断十分简单,仅仅是将第一个字符为 # 的内容全部忽略

对于 ”注释在行内“ 、”多行注释“ 等这样的内容是不能判断的,还有待学习优化。

4.函数封装

Shell 中用户自定义的函数不需要像 C 一样指明类型,函数返回值可以用 return 来返回, return后跟一个数值,范围为 0-255。如果不用 return,将以最后一条命令运行结果作为返回值。

  • 调用函数时可以向其传递参数,在函数内部使用 $n 的形式来获取参数的值。比如 $1表示第一个参数,$2表示第二个参数,当n>=10时,需要使用 ${n} 来获取参数,比如第十个参数 ${10}

  • 函数返回值在调用该函数后通过 $? 来获得。但是$? 仅对其上一条指令负责,一旦函数返回后其返回值没有立即保存入参数,那么其返回值将不再能通过 $? 获得,所以函数返回值必须第一时间使用或保存

有一点要注意的是,所有函数在使用前必须定义。所以说,应该将自定义函数放在脚本的开头部分,这样函数就可以正常使用了。

fileName="check_prog.conf"
program=""		# program为变量,用来接收参数

# 读取文件
getFile(){
	BASE_PATH=$(cd `dirname $0`; pwd)
	if [ ! -e "${BASE_PATH}/${fileName}" ]
	then
		echo "文件不存在或无法读取"
		exit 0
	fi
}
# 跳过注释
crossNote(){
	program=$1						# 接收传递的参数
	if [ "${program:0:1}" == "#" ]
	then
    		return 1				# 当前行为注释,返回1
	fi
}
# 判断进程
judgeProgress(){
	program=$1						# 接收传递的参数
	pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'`
	if [ "${pid}" == "" ]
	then
	    	echo "${program}: DOWN"
	else
    		echo -ne "${program}: "
			echo ${pid}
	fi
}

编写主函数,首先读取文件,然后每行都直接去掉注释,再判断进程是否在运行。

# 主函数
main(){
getFile fileName					# 判断文件存在
cat $fileName | while read line		# 按行读取文件
do
	crossNote $line					# 每一行判断注释
	if [ $? == 1 ]					# 返回值为1,当前行为注释,忽略
	then
		continue
	fi
	judgeProgress $line				# 判断进程是否运行
done
}
main

5.整体代码

#! /bin/bash
# 用于实现进程监控的shell脚本
fileName="check_procs.conf"
program=""

# 读取文件
getFile(){
	BASE_PATH=$(cd `dirname $0`; pwd)
	if [ ! -e "${BASE_PATH}/${fileName}" ]
	then
		echo "文件不存在或无法读取"
		exit 0
	fi
}
# 跳过注释
crossNote(){
	program=$1
	if [ "${program:0:1}" == "#" ]
	then
    		return 1
	fi
}
# 判断进程
judgeProgress(){
	program=$1
	#获得进程PID,为空则进程未启动
	pid=`ps -ef | grep $program | grep -v grep |awk '{print $2}'`
	if [ "${pid}" == "" ]
	then
	    	echo "${program}: DOWN"
	else
    		echo -ne "${program}: "
			echo ${pid}
	fi
}

# 主函数
main(){
getFile fileName
cat $fileName | while read line
do
	crossNote $line
	if [ $? == 1 ]
	then
		continue
	fi
	judgeProgress $line
done
}
main

运行脚本

如果在运行脚本时遇到了错误,请参考这篇文章进行解决 Shell脚本使用常见问题说明

我们在当前目录下输入 ll 命令,确认配置文件已经存在

s2

然后在终端中输入运行脚本的命令

./check_proc.sh

回车即可看到最终的运行结果

s1

参考文章

Linux常用命令

vim编辑器的常用技巧

Shell脚本使用常见问题说明

Shell 函数

kill -9 ps -ef|grep cpu|grep -v grep|awk '{print $2}'命令解析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值