• 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
    ",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
    ",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
    ",p_name,g_name,"NULL","Stopped","NULL","NULL","NULL"}'
        fi
    }
    
    # 打印头信息
    awk 'BEGIN{printf "%-20s%-20s%-20s%-20s%-20s%-20s%-20s
    ","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

      

  • 相关阅读:
    整合SSH遇到的问题
    学习动态代理实现业务层的事务控制遇到的问题
    docker局域网独立IP外网访问配置
    第23次CSP-D题解法
    Nordic Bluetooth 切换到DFU Mode
    MySQL事务、锁和MVCC
    深拷贝和浅拷贝的区别是什么?
    python是如何进行内存管理的
    数据库的事务
    斐波那契数列
  • 原文地址:https://www.cnblogs.com/crazymagic/p/11173162.html
Copyright © 2020-2023  润新知