shell 大型腳本工具開發實戰


 

拆分腳本功能,抽象函數

  • 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

 

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM