Shell编程—【10】大型脚本开发实战

1. 脚本工具功能概述

需求描述:

  • 实现一个脚本工具,该脚本提供类似supervisor功能,可以对进程进行管理;
  • 一键查看所有进程运行状态;
  • 单个或批量启动进程,单个或批量停止进程;
  • 提供进程分组功能,可以按组查看进程运行状态,可以按组启动或停止该组内所有进程;

2. 拆分脚本功能,抽象函数

  • function get_all_process 返回进程名称列表字符串"nginx httpd mysql datanode"
  • function get_all_group 返回进程组列表字符串
  • function get_process_info(该函数可以接收一个参数,参数为进程名称) 返回进程详细信息列表字符串,详细信息包括:运行状态、PID、CPU、MEM、启动时间
  • function get_all_process_by_group 返回进程组内的所有进程名称列表字符串 DB组--> "mysql postgresql oracle"

3. 功能函数

  • process.cfg
[GROUP_LIST]
WEB
DB
HADOOP
YARN

[WEB]
nginx
httpd

[DB]
mysql
postgresql
oracle

[HADOOP]
datanode
namenode
journalnode

[YARN]
resourcemanager
nodemanager

[nginx]
description="Web Server 1"
program_name=tail
parameter=-f /root/lesson/9.1/tmp/web-nginx.conf

[httpd]
description="Web Server 2"
program_name=tail
parameter=-f /root/lesson/9.1/tmp/web-httpd.conf

[mysql]
description="High Performance DataBase"
program_name=tail


$0 这个程式的执行名字
$n 这个程式的第n个参数值,n=1..9
$* 这个程式的所有参数,此选项参数可超过9个。
$# 这个程式的参数个数
$$ 这个程式的PID(脚本运行的当前进程ID号)
$! 执行上一个背景指令的PID(后台运行的最后一个进程的进程ID号)
$? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
$- 显示shell使用的当前选项,与set命令功能相同
$@$*类似,但是可以当作数组用	
#!/bin/bash

HOME_DIR="/root/lesson/9.1"
CONFIG_FILE="process.cfg"
this_pid=$$

#说明:该函数无需输入任何参数:返回配置文件process.cfg中所有的组信息,例如WEB、DB等
function get_all_group
{
	G_LIST=`sed -n '/\[GROUP_LIST\]/,/\[.*\]/p' $HOME_DIR$CONFIG_FILE | grep -v "^$" | grep -v "\[.*\]"`
	echo "$G_LIST"
}

#说明:该函数无需输入任何参数:返回配置文件process.cfg中所有的进程信息
function get_all_process
{
	for g in `get_all_group`
	do
		P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR$CONFIG_FILE | grep -v "^$" | grep -v "\[.*\]"`
		echo "$P_LIST"
	done
}

#说明:该函数接收一个参数,参数为进程名称:返回值是一个pid的列表,可能有一个pid,也可能有多个
function get_prcess_pid_by_name
{
	if[$# -ne 1];then
		return 1
	pids=`ps -ef | grep $1 | grep -v grep |grep -v $this_pid| grep -v $0| awk '{print $2}'`
	echo $pids
}

#说明:该函数接收一个参数,参数为进程pid:返回值是一个进程运行信息的列表,列表包含运行状态、cpu占用率、内存占用率、进程启动时间
function get_prcess_info_by_pid
{
	# -v 引入参数
	if[`ps -ef|awk -v pid=$1 '$2==pid{print}'| wc -l` -eq 1];then	
	    pro_status="RUNNING"
	else
		pro_status="STOPED"
	fi
	pro_cpu=`pa aux | awk -v pid=$1 '$2==pid{print $3}'`
	pro_mem=`pa aux | awk -v pid=$1 '$2==pid{print $4}'`
	pro_start_time=`pa -p $1 -o lstart|grep -v STARTED`
}

#说明:该函数接收一个参数,参数为组的名称:返回值是0或1,0代表该组在配置文件中,1代表该组不在
function is_group_in_config
{
	for gn in `get_all_group`;do
		if[$gn==$1];then
			return
		fi
	
	done
	echo "Group $1 is not in process.cfg"
	return 1
}

#说明:该函数接收一个参数,参数为j进程的名称:返回值是0或1,0代表该组在配置文件中,1代表该组不在
function is_process_in_config
{
	for pn in `get_all_process`;do
		if[$pn==$1];then
			return
		fi
	
	done
	echo "process $1 is not in process.cfg"
	return 1
}

#说明:该函数接收一个参数,参数为组名称:返回值是对应组内的所有进程名称列表
function get_all_process_by_group
{
	is_group_in_config $1
	# $? 执行上一个指令的返回值 (显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误)
	if[$? -eq 0];then
		p_list=`sed -n  "/\[$1\]/,/\[.*\]/p" $HOME_DIR$CONFIG_FILE |egrep -v "(^$|^#|\[.*\])"`
		echo p_list
	else
		echo "GroupName $1 is not in process.cfg"
	fi
}

#说明:该函数接收一个参数,参数是一个进程名称:返回值是一个组名
function get_group_by_process_name
{
	for gn in `get_all_group`;do
		for pn in `get_all_process_by_group $gn`;do
			if[$pn==$1];then
				echo "$gn"
			fi
		done
	done
}

#说明:该函数接收两个参数,第一个参数为process_name,第二个参数为组名称
#返回值,是针对每一个进程pid的运行信息格式化打印
function formate_print
{
	ps -ef|grep $1|grep -v grep |grep -v $this_pid $> /dev/null
	if[$? -eq 0];then
		pids=`get_prcess_pid_by_name $1`
		for pid in $pids;do
			get_prcess_info_by_pid $1
			awk -v p_name=$1 \
			-v g_name=$2 \
			-v p_status=$pro_status \
			-v p_pid=$pid \
			-v p_cpu=$pro_cpu \
			-v p_mem=$pro_mem \
			-v p_start_time="$pro_start_time" \
			'BEGIN{printf "%-20s%-10s%-10S%-6s%-7s%-10s%-20s\n",
			p_name,g_name,p_status,p_pid,p_cpu,p_mem,p_start_time}'
		done
	else
		awk -v p_name=$1 \
			-v g_name=$2 \ 
			'BEGIN{printf "%-20s%-10s%-10S%-6s%-7s%-10s%-20s\n",
			p_name,g_name,"STOPED","NULL","NULL","NULL","NULL"}'
	fi
}

   
if[!-e $HOME_DIR$CONFIG_FILE];then
		echo "$CONFIG_FILE is not exist..please check"
		exit 1   
#有
#程序主流程设计:
#	./app_status.sh执行有三种情况
#	1 无参数         列出配置文件中所有进程的运行信息
#	2 -g GroupName   列出GroupName组内的所有进程
#	3 process_name1  列出指定进程的运行信息

awk 'BEGIN{printf "%-20s%-10s%-10S%-6s%-7s%-10s%-20s\n","ProcessName----","GroupName----","Status----",
"PID----","CPU----","MEMORY----","StartTime----"}'	
	
if[$# -gt 0];then	
	if["$1" =="-g"];then
		shift
		for gn in $@;do
			is_group_in_config $gn ||continue
			for pn in `get_all_process_by_group $gn`;do
				is_process_in_config $pn && formate_print $pn $gn
			done
		done
	else
		for pn in $@;do
			gn=`get_group_by_process_name $pn` 
			is_process_in_config $pn && formate_print $pn $gn
		done
		
	fi
else
	for pn in `get_all_process`;do
		gn=`get_group_by_process_name $pn` 
		is_process_in_config $pn && formate_print $pn $gn
	done
fi
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值