拆分腳本功能,抽象函數
- 1、function get_all_group 返回進程組列表字符串
- 2、function get_all_process 返回進程名列表字符串"nginx httpd mysql datanode"
- 3、function get_process_info 返回進程詳細信息列表字符串,詳細信息包括:運行狀態、PID、CPU、MEM、啟動時間 注:該函數可以接收一個參數,參數為進程名稱
- 4、function get_all_process_by_group 返回進程組內的所有進程名稱列表字符串
配置文件
process.cfg
[GROUP_LIST] WEB DB HADOOP YARN [WEB] nginx httpd [DB] mysql postgresql oracle [HADOOP] datanode namenode journalnode [YARN] resourcemanager nodemanager
功能函數代碼 1 (獲取進程組列表)
sed -n '/\[GROUP_LIST]/,/\[.*\]/p' process.cfg | grep -v "^$" | grep -v "\[.*\]"
使用egrep 優化
sed -n '/\[GROUP_LIST]/,/\[.*\]/p' process.cfg | egrep -v "(^$|\[.*\])"
封裝函數
app_status.sh
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR="/home/roo/Desktop/shell_code/day9" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } for g in `get_all_group`;do echo $g done
執行腳本
sh app_status.sh
功能函數代碼 2 (獲取每個進程組中的進程)
app_status.sh
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR="/home/roo/Desktop/shell_code/day9" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } #for g in `get_all_group`;do # echo $g #done function get_all_process { for g in `get_all_group` do P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"` echo $P_LIST done } echo `get_all_process`
執行腳本
sh app_status.sh
功能函數代碼 3 (獲取每個進程組中的進程、返回進程詳細信息列表字符串,詳細信息包括:運行狀態、PID、CPU、MEM、啟動時間)
ps -aux | grep nginx
第二列是進程的id第三列是cpu使用率,第四列是內存使用率
功能拆分1 :
get_process_pid_by_name 根據進程的名字獲取進程 id
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR="/home/roo/Desktop/shell_code/day9" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } #for g in `get_all_group`;do # echo $g #done function get_all_process { for g in `get_all_group` do P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"` echo $P_LIST done } this_pid=$$ function get_process_pid_by_name # 獲取進程的pid { if [ $# -ne 1 ];then return 1 else #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'` pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'` echo $pids fi } get_process_pid_by_name $1
執行腳本
sh app_status.sh nginx
功能拆分2 :
get_process_info_by_pid 根據進程 id 獲取進程詳細信息
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR="/home/roo/Desktop/shell_code/day9" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } #for g in `get_all_group`;do # echo $g #done function get_all_process { for g in `get_all_group` do P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"` echo $P_LIST done } this_pid=$$ function get_process_pid_by_name # 獲取進程的pid { if [ $# -ne 1 ];then return 1 else #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'` pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'` echo $pids fi } function get_process_info_by_pid # 獲取進行信息 { # awk 中引入一個變量 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=`ps aux | awk -v pid=$1 '$2==pid{print $3}'` pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'` pro_start_time=`ps -p $1 -o lstart | grep -v STARTED` } get_process_info_by_pid $1 echo "$pro_status $pro_cpu $pro_mem $pro_start_time"
運行腳本
sh app_status.sh 1229
功能函數代碼 4
is_group_in_config: 判斷輸入的組是否在配置文件中
get_all_process_by_group: 根據輸入的組輸出當前組下的進程名
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR="/home/roo/Desktop/shell_code/day9" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } #for g in `get_all_group`;do # echo $g #done function get_all_process { for g in `get_all_group` do P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"` echo $P_LIST done } this_pid=$$ function get_process_pid_by_name # 獲取進程的pid { if [ $# -ne 1 ];then return 1 else #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'` pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'` echo $pids fi } function get_process_info_by_pid # 獲取進行信息 { # awk 中引入一個變量 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=`ps aux | awk -v pid=$1 '$2==pid{print $3}'` pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'` pro_start_time=`ps -p $1 -o lstart | grep -v STARTED` } function is_group_in_config { # 如果遍歷不存在就返回1 for gn in `get_all_group`;do if [ "$gn" == "$1" ];then return fi done return 1 } function get_all_process_by_group { is_group_in_config $1 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 } is_group_in_config $1 && echo exist || echo not exist get_all_process_by_group $1
執行腳本
sh app_status.sh WEB
程序主流程設計及代碼實現
app_status.sh 執行有三種情況
- 1、無參數 列出配置文件中所有進程的運行信息
- 2、-g GroupName 列出GroupName組內的所有進程
- 3、process_name1 列出指定進程的運行信息
function get_all_group 說明:該函數無需輸入任何參數:返回配置文件 process.cfg中所有的組信息,例如web,db等 function get_all_process 說明:該函數無需輸入任何參數:返回配置文件 process.cfg中所有的進程信息 function get_process_pid_by_name 說明:該函數接收一個參數,參數為進程名稱:返回值是一個PID的列表,可能有一個PID,也可能有多個 function get_process_info_by_pid 說明:該函數接收一個參數,參數為進程PID;返回值是一個進程運行信息的列表,列表包含運行狀態:CPU占用率、內存占用率、進程運行時間 function is_group_in_config 說明 :該函數接收一個參數,參數為組的名稱;返回值是0或1,0代表該組在配置文件中,1代表該組不在配置文件中 function get_all_process_by_group 說明:該函數接收一個參數,參數為組名稱:返回值是對應組內的所有進程名稱列表 function get_group_by_process_name 說明:該函數接收一個參數,參數是一個進程名稱:返回值是一個組名 function format_print 說明:該函數接收兩個參數,第一個參數為process_name,第二個參數為組名稱 返回值,是針對每一個進程PID的運行信息 function is_process_in_config 說明:該函數接收一個參數,參數為進程名稱;返回值是0或1,0代表該進程在配置文件中,1代表進程不在配置文件中
#!/bin/bash # # Func: Get Process Status In process.cfg # Define Variables HOME_DIR=""/home/roo/Desktop/shell_code/day9"" CONFIG_FILE="process.cfg" # 進程本身的pid this_pid=$$ # 獲取所有的組 function get_all_group { G_LIST=$(sed -n '/\[GROUP_LIST]/,/\[.*\]/p' $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])") echo $G_LIST } #for g in `get_all_group`;do # echo $g #done # 獲取所有進程 function get_all_process { for g in `get_all_group` do P_LIST=`sed -n "/\[$g\]/,/\[.*\]/p" $HOME_DIR/$CONFIG_FILE | egrep -v "(^$|\[.*\])"` echo $P_LIST done } # 通過pid獲取進程名稱 function get_process_pid_by_name { if [ $# -ne 1 ];then return 1 else #pids=`ps -ef | grep $1 | grep -v grep | grep -v $this_pid |grep -v $0| awk '{print $2}'` pids=`ps -ef | grep $1 | grep -v grep | grep -v $0| awk '{print $2}'` echo $pids fi } # 通過pid 獲取進程信息 function get_process_info_by_pid { # awk 中引入一個變量 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=`ps aux | awk -v pid=$1 '$2==pid{print $3}'` pro_mem=`ps aux | awk -v pid=$1 '$2==pid{print $4}'` pro_start_time=`ps -p $1 -o lstart | grep -v STARTED` #echo "pro_status=$pro_status" #echo "pro_cpu=$pro_cpu" #echo "pro_mem=$pro_mem" #echo "pro_start_time=$pro_start_time" } # 判斷輸入的組是否在配置文件中 function is_group_in_config { # 如果遍歷不存在就返回1 for gn in `get_all_group`;do if [ "$gn" == "$1" ];then return 0 fi done echo "Group $1 is not in process.cfg" return 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 { # 判斷輸入的組名是否在group中 is_group_in_config $1 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 #echo "pn=$pn" if [ $pn == $1 ];then echo "$gn" fi done done } #if [ ! -e $HOME_DIR/$CONFIG_FILE ];then # echo "$CONFIG_FILE is not exists..please check.." #fi #is_group_in_config $1 && echo "exists" || echo "not exists" #get_all_process_by_group $1 function format_print { ps -ef | grep $1 | grep -v grep | grep -v $this_pid &> /dev/null if [ $? -eq 0 ];then pids=`get_process_pid_by_name $1` #echo "pids=$pids" for pid in $pids;do get_process_info_by_pid $pid 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%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,p_status,p_pid,p_cpu,p_mem,p_start_time}' # -v 定義的參數需要用雙引號引起來"",否則會報錯 awk: fatal: cannot open file `15' for reading (No such file or directory),主要是因為 p_start_time 中間有空格,需要""雙引號引起來 #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%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,p_pid,p_status,p_cpu,p_mem,p_start_time}' done else awk -v p_name=$1 -v g_name=$2 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n",p_name,g_name,"NULL","Stopped","NULL","NULL","NULL"}' fi } # 打印頭信息 awk 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s\n","ProcessName---","GroupName---","Status---","Pid---","CPU---","MEMORY---","StartTime---"}' if [ $# -gt 0 ];then # 傳遞的是組 if [ "$1" == "-g" ];then shift # 遍歷傳遞參數的組 for gn in $@;do # 組名是否在配置文件中, 執行不成功才會 continue 跳過 is_group_in_config $gn || continue for pn in `get_all_process_by_group $gn`;do is_process_in_config $pn && format_print $pn $gn done done # 傳遞的是進程名 else for pn in $@;do gn=`get_group_by_process_name $pn` is_process_in_config $pn && format_print $pn $gn done fi else # 不添加參數,打印所有進程 for pn in `get_all_process`;do gn=`get_group_by_process_name $pn` #echo "gn=$gn, pn=$pn" is_process_in_config $pn if [ $? -eq 0 ];then #echo "format print" format_print $pn $gn fi done fi #format_print nginx WEB #group_name=`get_group_by_process_name $1` #echo $group_name
執行腳本 輸出所有組內的進程信息
sh app_status1.sh
執行腳本 輸出指定組內的進程信息
sh app_status1.sh -g WEB
輸出指定組內單個進程的信息
sh app_status1.sh -g WEB DB