因为项目需求,需要对部分定时任务的进程进行监控,其中脚本的重点是获取指定进程的运行时长,并直接杀死超过指定时长的进程,这里记录一下整个脚本:
#!/bin/bash
# 函数的参数为过滤出的进程信息,然后进行运行时间的处理
function time_handler() {
# 获取进程执行时间的信息列,格式有三种,min:sec,h:m:s,d-h:m:s
exec_time=`echo $1 | awk '{print $2}'`
# 获取exec_time变量的时间组成部分的数量
time_field_count=`echo $exec_time | awk -F ':' '{print NF}'`
# 获取倒数第二列数据,即分钟数
count_minutes=`echo $exec_time | awk -F ':' '{print $(NF-1)}'`
# 判断当前exec_time变量的数据属于哪种格式,如果是第一种,则天数,小时为0
if [ $time_field_count -lt 3 ];then
count_hours=0
count_days=0
else
# 如果判断不是第一种,还需要判断是否属于第二或第三种格式,并把对应的day,hours赋值给变量
count_hours=`echo $exec_time | awk -F ':' '{print $(NF-2)}'`
fields=`echo $count_hours |awk -F '-' '{print NF}'`
if [ $fields -ne 1 ];then
count_days=`echo $count_hours | awk -F '-' '{print $1}'`
count_hours=`echo $count_hours | awk -F '-' '{print $2}'`
else
count_days=0
fi
fi
# 以分钟为单位,计算总的分钟数
elapsed_minutes=`expr $count_days \* 1440 + $count_hours \* 60 + $count_minutes`
}
while true;do
# 获取进程信息,通过grep过滤需要的进程,并写入到文件,ps的etime参数即为进程运行时长
process_list=`ps -eo pid,etime,cmd |grep -E 'magento queue:consumers'\|'magento cron:run'\|'magento setup:cron:run' |grep -v "grep" | tee result.txt`
# 判断当前是否过滤到所需要的进程信息,没有则重新获取ps信息
if test -z "$process_list";then
continue
fi
# 按行读取文件信息,每一行为一个进程信息。
cat result.txt | while read line;do
# 获取进程的pid
pid=`echo $line | awk '{print $1}'`
# 交给函数time_handler计算运行总时长
time_handler "$line"
# 判断运行时长是否超过指定时间,如果超过,则直接杀死进程。
if [ $elapsed_minutes -gt 60 ];then
echo "pid: $pid process is running $elapsed_minutes minutes."
# 反复判断进程是否已被杀死。
while [ `ps -eo pid | grep $pid | grep -v "grep"` ];do
echo "killing pid:$pid process...."
kill -9 $pid
done
echo "kill pid: $pid process success!"
fi
done
sleep 30
done
其中,ps命令的 -eo 选项,是指定需要输出的信息,这里指定输出了pid,运行时间etime和cmd详细命令,输出的格式如下:
[root@localhost 2020TNT-1021]# ps -eo pid,etime,cmd
PID ELAPSED CMD
18496 2-08:43:09 sshd: root@pts/1
18498 2-08:43:08 -bash
34092 06:31:13 [kworker/0:1]
44152 1-23:53:06 [kworker/u256:0]
50538 52:41 [kworker/u256:2]
51102 41:00 [kworker/1:0]
51962 23:08 pickup -l -t unix -u
52071 20:54 [kworker/1:2]
53034 00:50 [kworker/1:1]
53075 00:00 ps -eo pid,etime,cmd
可以看到etime的三种格式,另外在对写入文件的进行信息进行循环读取时,如果使用for line in file
进行读取,会由于每一行存在空格,导致读取出来的数据不正确,这里使用cat file.txt|while read line
按行进行循环读取。